【问题标题】:Optimization for Matrix Multiply (OpenMP) - C矩阵乘法优化 (OpenMP) - C
【发布时间】:2017-11-15 08:33:42
【问题描述】:

我正在学习一点关于 openMP 的知识,并尝试在这里使用它来将两个矩阵相乘。

void matrix_multiply(matrix *A, matrix *B, matrix *C) {

    #pragma omp parallel
    {
        #pragma omp for 
        for(int i = 0; i < A->dim.rows; i++) {
            for(int j = 0; j < B->dim.cols; j++) {
                C->data[i][j] = 0;
                for (int k = 0; k < A->dim.cols; k++) {
                C->data[i][j] += A->data[i][k] * B->data[k][j];
               }
           }
       }
   }
}

typedef struct shape {
    int rows;
    int cols;
} shape;

typedef struct matrix {
    shape dim;
    float** data;
} matrix;

对此还有点新意,那么是否有任何简单的更改来提高性能或者我已经这样做了?我是否也因为不使用归约而陷入任何数据竞争?

【问题讨论】:

    标签: c matrix openmp


    【解决方案1】:

    您当前的实现可能不会有很大改进。在这一点上,它归结为编译器和缓存的使用。 here by Intel 提出了一个有趣的观点,即 GCC 需要交换两个循环才能向量化乘法(即使用 SIMD)。对于非常大的矩阵,您可以考虑不将矩阵划分为条带,而是划分为块。这会带来复杂性和开销,但可以提高缓存的使用率。

    仅当您将单个变量与多个线程相加时才需要归约子句,这里不是这种情况,因为您只对 k 求和。

    最后(但这完全是个人的)请注意,您可以将两个指令替换为单个指令

    #pragma omp parallel for
    

    在我看来,它看起来更干净一些。

    【讨论】:

    • 如果这是一个教学练习(即学习如何使用 OpenMP),很好。如果您想要高性能矩阵乘法,请立即停止。而是去寻找诸如英特尔 MKL 之类的库,它们具有更多优化(例如缓存阻塞)。确实,将幼稚并行化的性能与 MKL 的性能进行比较可能会很有趣...
    猜你喜欢
    • 2021-02-06
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    相关资源
    最近更新 更多