我在open MP中实现并行点积
我有这个密码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <omp.h>
#define SIZE 1000

int main (int argc, char *argv[]) {

  float u[SIZE], v[SIZE], dp,dpp;
  int i, j, tid;

  dp=0.0;
  for(i=0;i<SIZE;i++){
      u[i]=1.0*(i+1);
      v[i]=1.0*(i+2);
  }
  printf("\n values of u and v:\n");

  for (i=0;i<SIZE;i++){
      printf(" u[%d]= %.1f\t v[%d]= %.1f\n",i,u[i],i,v[i]);
  }
  #pragma omp parallel shared(u,v,dp,dpp) private (tid,i)
  {
      tid=omp_get_thread_num();

      #pragma omp for private (i)
      for(i=0;i<SIZE;i++){
          dpp+=u[i]*v[i];
          printf("thread: %d\n", tid);
      }
      #pragma omp critical
      {
          dp=dpp;
          printf("thread %d\n",tid);
      }


  }

  printf("\n dot product is %f\n",dp);

 }

我从:pgcc -B -Mconcur -Minfo -o prog prog.c
我在控制台得到的结果是:
33, Loop not parallelized: innermost

39, Loop not vectorized/parallelized: contains call

48, Loop not vectorized/parallelized: contains call

我做错什么了?
在我看来,一切看起来都很好。

最佳答案

首先,一个简单的1000元素的点产品没有足够的计算成本来证明多线程是合理的——你将付出比你在性能上获得的更多的通信和同步成本,这是不值得的。
其次,它看起来像是在计算每个线程中的全点积,而不是将计算分成多个线程并在最后合并结果。
下面是一个如何从https://computing.llnl.gov/tutorials/openMP/#SHARED

#include <omp.h>

main ()
{
  int   i, n, chunk;
  float a[100], b[100], result;

  /* Some initializations */
  n = 100;
  chunk = 10;
  result = 0.0;
  for (i=0; i < n; i++) {
      a[i] = i * 1.0;
      b[i] = i * 2.0;
  }

  #pragma omp parallel for      \
      default(shared) private(i)  \
      schedule(static,chunk)      \
      reduction(+:result)

    for (i=0; i < n; i++)
        result += (a[i] * b[i]);

  printf("Final result= %f\n",result);
}

基本上,当您有大量昂贵的循环时,OpenMP有利于执行粗粒度并行。一般来说,当你在做并行编程时,在重新同步之前,你能做的“大块”计算越大越好。尤其是随着内核数量的增加,通信和同步成本也会增加。假设每次同步(获取要执行的新索引或索引块、输入关键部分等)花费10毫秒或1百万条指令,以便更好地了解何时/何地/如何并行代码。

关于c - 打开MP-点产品,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5368038/

10-12 16:09