【问题标题】:Parallelizing Factorial Calculation并行化阶乘计算
【发布时间】:2016-01-24 16:24:07
【问题描述】:

我想编写一个使用并行计算(Open MP library)计算整数阶乘的程序。

显然下面的程序存在竞争条件。

// Each loop iteration writes a value that a different iteration reads.
#pragma omp parallel for
for (i=2; i < 10; i++)
{
   factorial[i] = i * factorial[i-1];
}

我在某处读到 pow 和阶乘计算无法并行完成。那么,这是真的吗,还是可以修改上述程序(在 C 中,使用 OPenMP 库)以并行计算阶乘?

【问题讨论】:

  • 顺便说一句,你为什么想要一个阶乘数组?阶乘的大小增长得非常快。您可能应该以某种方式规范化该值以使其有界。另请参阅Stirling's_approximation

标签: c parallel-processing openmp factorial


【解决方案1】:

您可以通过在数组上运行两次来并行执行此操作。第一次计算部分产品并保存每个线程的总部分产品。在第二遍中,您通过前一个线程的总产品更正每个元素。这类似于如何并行进行累积和(也称为前缀和),只是它是并行累积乘积。

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

int main(void) {
    int n = 10;
    int factorial[n];
    factorial[1] = 1;

    int *proda;
    #pragma omp parallel
    {
        int ithread = omp_get_thread_num();
        int nthreads = omp_get_num_threads();
        #pragma omp single
        {
            proda = malloc(nthreads * sizeof *proda);
            proda[0] = 1;
        }
        int prod = 1;
        #pragma omp for schedule(static) nowait
        for (int i=2; i<n; i++) {
            prod *= i;
            factorial[i] = prod;
        }
        proda[ithread+1] = prod;
        #pragma omp barrier
        int offset = 1;
        for(int i=0; i<(ithread+1); i++) offset *= proda[i];
        #pragma omp for schedule(static)
        for(int i=1; i<n; i++) factorial[i] *= offset;
    }
    free(proda);

    for(int i=1; i<n; i++) printf("%d\n", factorial[i]); putchar('\n'); 
}

【讨论】:

    【解决方案2】:

    如果它是一个很大的数字,你可以做一个并行阶乘,如果你分裂你的乘法

    示例

    数字是 1000!你有 10 个线程

    1. 线程解析2*3*4*5*.....*100并保存在t1中
    2. 线程解析 101*102*103 .... *200 并保存在 t2 中

      ....

    10) 线程解析 900*901*902*....*1000 并保存到 t10

    然后在你解决的主线程上:

    t1*t2*t3*...*t10 等于1000!

    【讨论】:

      猜你喜欢
      • 2022-01-17
      • 1970-01-01
      • 2023-03-22
      • 2015-04-19
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      • 2021-11-16
      • 2016-11-29
      相关资源
      最近更新 更多