矩阵乘法的OpenMP性能问题

用户名

我在使用OpenMp时遇到性能问题。我正在尝试测试不使用OpenMP的单线程程序和使用OpenMP的应用程序的结果。通过在线比较矩阵链乘法程序的结果,openMP的实现速度是后者的2到3倍,但是我的实现对于两个应用程序来说都是相同的速度。我实施openMP的方式不正确吗?openMP上的任何指针以及如何正确实现?任何帮助深表感谢。提前致谢。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main( int argc , char *argv[] ) 
{
   srand(time(0));
   if ( argc != 2 )
   {
      printf("Usage: %s <size of nxn matrices>\n", argv[0]);
      return 1; 
   }

   int n = atoi( argv[1] );
   int a, b;
   double A[n][n], B[n][n], C[n][n];
   FILE *fp;
   fp = fopen("/home/mkj0002/CPE631/Homework2/ArrayTry/matrixResults", "w+"); //For the LeCASA machine

   for(a = 0; a < n; a++)
   {
       for(b = 0; b < n; b++)
       {
          A[a][b] = ((double)rand()/(double)RAND_MAX);  //Number between 0 and 1
          A[a][b] = (double)rand();         //Number between 0 and RAND_MAX
          B[a][b] = ((double)rand()/(double)RAND_MAX);  //Number between 0 and 1
          B[a][b] = (double)rand();         //Number between 0 and RAND_MAX
          C[a][b] = 0.0;
       }
    }

    #pragma omp parallel shared(A,B,C)
    {
        int i,j,k;
        #pragma omp for schedule(guided,n)
        for(i = 0; i < n; ++i)
        {
            for(j = 0; j < n; ++j)
            {
                double sum = 0;
                for(k = 0; k < n; ++k)
                {
                    sum += A[i][k] * B[k][j];
                }

                C[i][j] = sum;
                fprintf(fp,"0.4lf",C[i][j]);
            }
        }
    }

    if(fp)
    {
        fclose(fp);
    }
    fp = NULL;

    return 0;
}                  
鼻子知道所有

(1)不要在并行区域内执行I / O。将其移出并C同时将许多变量写入文件时,您会看到瞬时加速

(2)完成上述操作后,应将调度更改为,static因为每个循环将执行完全相同的计算量,并且不再需要花哨的调度来产生开销。

(3)此外,为了更好地利用缓存,应交换jk循环。要看到这一点,想象一下B在当前循环中仅访问变量。

for(j = 0; j < n; ++j)
{
    for(k = 0; k < n; ++k)
    {
        B[k][j] += 5.0;
    }
}

您可以看到它如何访问B,就像它以Fortran的列主格式存储一样。更多信息可以在这里找到更好的选择是:

for(k = 0; k < n; ++k)
{
    for(j = 0; j < n; ++j)
    {
        B[k][j] += 5.0;
    }
}

回到您的示例,我们仍然必须处理sum变量。一个简单的建议是存储当前sum正在计算的当前行,然后在完成当前循环后将其全部保存。

结合所有3个步骤,我们得到如下结果:

#pragma omp parallel shared(A,B,C)
{
    int i,j,k;
    double sum[n]; // one for each j

    #pragma omp for schedule(static)
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
            sum[j] = 0;

        for(k = 0; k < n; ++k)
        {
            for(j = 0; j < n; ++j)
            {
                sum[j] += A[i][k] * B[k][j];
            }
        }

        for(j = 0; j < n; ++j)
            C[i][j] = sum[j];
    }
}

// perform I/O here using contiguous blocks of C variable

希望能有所帮助。

编辑:根据@Zboson的建议,将其完全删除sum[j]并用C[i][j]整个程序替换它甚至会更容易

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

CUDA矩阵乘法的性能

来自分类Dev

CUDA矩阵乘法的性能

来自分类Dev

矩阵乘法问题

来自分类Dev

Java问题中的矩阵乘法

来自分类Dev

LU分解的矩阵乘法问题?

来自分类Dev

numpy矩阵乘法的奇怪性能结果

来自分类Dev

嵌套循环与硬编码矩阵乘法的性能

来自分类Dev

Eigen3矩阵乘法性能

来自分类Dev

Python-矩阵乘法代码问题

来自分类Dev

OpenMP C ++矩阵乘法并行运行较慢

来自分类Dev

使用OpenMP(C)进行矩阵乘法-折叠所有循环

来自分类Dev

OpenMP性能问题中的嵌套循环

来自分类Dev

openMp的多个独立for循环的性能问题

来自分类Dev

最高不能超过50%。矩阵乘法的理论性能

来自分类Dev

矩阵乘法:为什么非阻塞的性能好于阻塞?

来自分类Dev

最高不能超过50%。矩阵乘法的理论性能

来自分类Dev

使用for循环的矩阵乘法会降低性能吗?

来自分类Dev

omp并行不会给矩阵乘法带来任何性能提升

来自分类Dev

矩阵乘法和带有加速框架的逆问题

来自分类Dev

RcppEigen-此矩阵乘法有什么问题?

来自分类Dev

Java中二维矩阵乘法的问题

来自分类Dev

矩阵链乘法和一些不同的问题?

来自分类Dev

Java中二维矩阵乘法的问题

来自分类Dev

重载矩阵乘法“ *”运算符有问题

来自分类Dev

Matlab R2012b中矩阵乘法的精度问题

来自分类Dev

实现矩阵乘法的施特拉森算法的问题

来自分类Dev

openmp的性能

来自分类Dev

openmp的性能

来自分类Dev

稀疏矩阵矩阵乘法