首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >打开MP - dot产品

打开MP - dot产品
EN

Stack Overflow用户
提问于 2011-03-20 19:01:15
回答 2查看 6.4K关注 0票数 1

我在open MP中实现了并行点积。

我有这样的代码:

代码语言:javascript
复制
#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开始

我在控制台中得到的结果是:

代码语言:javascript
复制
33, Loop not parallelized: innermost 

39, Loop not vectorized/parallelized: contains call

48, Loop not vectorized/parallelized: contains call

我做错了什么?

在我看来,一切看起来都很好。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-20 20:47:14

首先,一个简单的1000个元素的点积没有足够的计算成本来证明多线程是合理的-您将在通信和同步成本上付出比您在性能上获得的更多的成本,这是不值得的。

其次,它看起来像是在每个线程中计算完整的点积,而不是在多个线程之间划分计算并在最后组合结果。

下面是一个如何在https://computing.llnl.gov/tutorials/openMP/#SHARED中计算向量点乘积的示例

代码语言:javascript
复制
#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毫秒,或100万条指令,以便更好地了解何时/何处/如何并行你的代码。

票数 4
EN

Stack Overflow用户

发布于 2011-03-20 21:10:22

这个问题和你最近提出的问题是一样的。您在一个变量中累加值,您必须告诉OpenMp如何做到这一点:

代码语言:javascript
复制
#pragma omp for reduction(+: dpp)
for(size_t i=0; i<SIZE; i++){
  dpp += u[i]*v[i];
}

使用循环局部变量作为索引,这就是你所需要的,忘掉你围绕它所做的所有事情。如果你想知道编译器对你的代码做了什么,用-S运行它,并检查汇编器的输出。这可能非常有指导意义,因为这样您就可以了解这样的简单语句在被并行化时会达到什么程度。

并且不要使用int作为循环索引。大小和类似的东西都是size_t

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5368038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档