我在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/