我正在学习一些有关 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;
对此仍然有点陌生,那么是否有任何简单的更改可以提高性能或者我已经做到了?另外,我是否会因不使用缩减而遇到任何数据竞争?
利用 SIMD,它现在随 OpenMP 一起提供(检查编译器可用性 - 并非所有编译器都提供 SIMD)。你可以这样实现:
#pragma omp parallel for
for(int i = 0; i < A->dim.rows; i++) {
for(int j = 0; j < B->dim.cols; j++) {
C->data[i][j] = 0;
#pragma omp simd
for (int k = 0; k < A->dim.cols; k++) {
C->data[i][j] += A->data[i][k] * B->data[k][j];
}
}
}
考虑连续内存分配的影响及其对 SIMD 指令和访问速度的影响。通常,这使得 SIMD 操作“行快”而“列慢”。这应该会影响您分配内存的方式。