我在使用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)此外,为了更好地利用缓存,应交换j
和k
循环。要看到这一点,想象一下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] 删除。
我来说两句