看看这段代码:
#include <stdio.h>
#include <omp.h>
int main()
{
long i, j;
#pragma omp for
for(i=0;i<=100000;i++)
{
for(j=0;j<=100000;j++)
{
if((i ^ j) == 5687)
{
//printf("%ld ^ %ld\n", i, j);
break;
}
}
}
}
所以,结果:
robotex@robotex-work:~/Projects$ gcc test.c -fopenmp -o test_openmp
robotex@robotex-work:~/Projects$ gcc test.c -o test_noopenmp
robotex@robotex-work:~/Projects$ time ./test_openmp
real 0m11.785s
user 0m11.613s
sys 0m0.008s
robotex@robotex-work:~/Projects$ time ./test_noopenmp
real 0m13.364s
user 0m13.253s
sys 0m0.008s
robotex@robotex-work:~/Projects$ time ./test_noopenmp
real 0m11.955s
user 0m11.853s
sys 0m0.004s
robotex@robotex-work:~/Projects$ time ./test_openmp
real 0m15.048s
user 0m14.949s
sys 0m0.004s
怎么了?为什么OpenMP程序更慢?我该如何纠正?
我使用OS Ubuntu在多台计算机(工作中的Intel Core i5,家中的Intel Core2Duo T7500)上测试了它,并且总是得到相同的结果:OpenMP不会显着提高性能。
我还测试了维基百科的例子并得到了相同的结果。
答案 0 :(得分:17)
您的代码中存在两个问题:
parallel
。所以它只使用1个线程。j
上遇到竞争条件,因为它已声明在并行区域之外。首先,您需要parallel
来实际并行运行OpenMP:
#pragma omp parallel for
其次,您在并行区域外声明j
。这将使它在所有线程之间共享。所以所有线程都在并行区域内读取和修改它。
因此,您不仅具有竞争条件,而且所有失效导致的缓存一致性流量正在扼杀您的表现。
您需要做的是为每个帖子设置j
本地。这可以通过以下任一方式完成:
j
。private(j)
添加到pragma:#pragma omp parallel for private(j)
请改为尝试:
int main()
{
double start = omp_get_wtime();
long i;
#pragma omp parallel for
for(i=0;i<=100000;i++)
{
long j;
for(j=0;j<=100000;j++)
{
if((i ^ j) == 5687)
{
//printf("%ld ^ %ld\n", i, j);
break;
}
}
}
double end = omp_get_wtime();
printf("%f\n",end - start);
return 0;
}
No OpenMP: 6.433378
OpenMP with global j: 9.634591
OpenMP with local j: 2.266667