Rob*_*tex 1 c performance gcc openmp
看看这段代码:
#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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以,结果:
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
Run Code Online (Sandbox Code Playgroud)
怎么了?为什么OpenMP程序更慢?我该如何纠正?
我使用OS Ubuntu在几台计算机(工作中的Intel Core i5,家中的Intel Core2Duo T7500)上测试了它,并且总是得到相同的结果:OpenMP不会显着提高性能.
我还测试了维基百科的例子并获得了相同的结果.
Mys*_*ial 17
您的代码中存在两个问题:
parallel你的pragma.所以它只使用1个线程.j因为它在并行区域之外声明.首先,您需要parallel实际并行运行OpenMP:
#pragma omp parallel for
Run Code Online (Sandbox Code Playgroud)
其次,你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;
}
Run Code Online (Sandbox Code Playgroud)
No OpenMP: 6.433378
OpenMP with global j: 9.634591
OpenMP with local j: 2.266667
Run Code Online (Sandbox Code Playgroud)