【问题标题】:Negative speedup When parallelising Vector Vector dot product并行化向量向量点积时的负加速
【发布时间】:2016-04-27 21:50:01
【问题描述】:

我有一个计算大向量的向量点积的子程序。我使用 open MP 将其并行化。以下是我的代码:

double scalarProd(double* vec1, double* vec2, int n){
double prod = 0.0;
int chunk = 10; 
int i;
//double* c = (double*) malloc(n*sizeof(double));

omp_set_num_threads(4);

#pragma omp parallel
{
    double pprod = 0.0;
    #pragma omp for
    for(i=0;i<n;i++) {
        pprod += vec1[i]*vec2[i];
    }

    #pragma omp critical
    for(i=0;i<n;i++) {
        prod += pprod;
    }
}

返回产品; }

谁能告诉我这里出了什么问题?我是多线程的新手

编辑:

添加更多信息。抱歉,第一次来这里。

上面提到的子程序是从我的函数 ConjugateGradient() 中多次调用的。我现在在我的 ConjugateGradient 函数中添加了时间计算代码,如下所示:

start_dotprod = omp_get_wtime();
rm_rm_old = scalarProd(rm,rm,MAT->ncols);
    run_dotprod = omp_get_wtime() - start_dotprod;
fprintf(timing,"Time taken by rm_rm dot product : %lf \n",run_dotprod);

观察结果:点积所用时间 连续版本:0.000007s 并行版本:0.002110

我正在我的英特尔 I7 笔记本电脑上的 Linux 操作系统上使用 gcc -fopenmp 命令进行简单编译。

我目前正在使用大小为 n = 5000 的矩阵。

由于同一个点积被多次调用直到收敛(大约 80k 次),我的整体速度大幅下降。

请建议我任何改进。我觉得我做错了什么。

谢谢! :)

【问题讨论】:

  • C 和 C++ 是不同的语言;删除你不使用的标签。
  • 您是否有机会使用clock() 来测量Linux 上的执行时间?
  • 欢迎来到 SO!请为您的问题提供更多背景信息:多少线程,什么硬件(CPU),您如何测量时间,什么向量大小。另请提供minimal reproducible example
  • 什么编译器?什么编译器选项?您是否进行了优化编译(例如 -O3 使用 GCC/Clang/ICC 或 /O2 使用 MSVC)?你是怎么计时的? n 的大小是多少? 85s 很长很长,所以要么你没有使用优化,要么n 非常大,在这种情况下,操作受内存带宽限制,并行版本不会比串行版本快很多。

标签: c multithreading openmp


【解决方案1】:

Prod 对于每个线程都是私有的,但它的值取决于之前的迭代。试试:

prod[i]+=vec1[i]*vec2[i];

【讨论】:

  • 不,prod 是一个归约变量。
猜你喜欢
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
相关资源
最近更新 更多