2016-01-24 210 views
2

我想要写,其计算的整数的阶乘,使用并行计算(开放MP库)的程序。并行化计算阶乘

明显低于计划从比赛状态受到影响。

// 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]; 
} 

我读的地方,战俘和阶乘计算可以以任何方式进行平行,这是真的还是上面的程序(C,使用OpenMP库)可以修改计算阶乘paralelley?

感谢。

+0

顺便说一句,为什么你想要一个阶乘数组?阶乘的大小增长非常迅速。你可能应该正常化的价值,以保持它有限。另见[Stirling's_approximation](https://en.wikipedia.org/wiki/Stirling's_approximation)。 –

回答

2

您可以在阵列上运行两次平行做到这一点。第一次计算部分产品并保存每个线程的总体部分产品。在第二遍中,您将通过前一个线程的总产品更正每个元素。这与如何并行执行累计和(又名前缀和)类似,除了它是并行累积产品。

#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!