2012-04-10 20 views
1

看看這段代碼: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; 
      } 
     } 
    } 
} 

所以,結果是:

[email protected]:~/Projects$ gcc test.c -fopenmp -o test_openmp 
[email protected]:~/Projects$ gcc test.c -o test_noopenmp 
[email protected]:~/Projects$ time ./test_openmp 
real 0m11.785s 
user 0m11.613s 
sys 0m0.008s 
[email protected]:~/Projects$ time ./test_noopenmp 

real 0m13.364s 
user 0m13.253s 
sys 0m0.008s 
[email protected]:~/Projects$ time ./test_noopenmp 

real 0m11.955s 
user 0m11.853s 
sys 0m0.004s 
[email protected]:~/Projects$ time ./test_openmp 

real 0m15.048s 
user 0m14.949s 
sys 0m0.004s 

有什麼不對?爲什麼OpenMP程序較慢?我該如何糾正它?

我使用OS Ubuntu在幾臺計算機上測試了它(Intel Core i5在工作,Intel Core2Duo T7500在家中),並且總是得到相同的結果:OpenMP不會顯着提高性能。

我也測試了維基百科的例子,得到了同樣的結果。

+0

你確定你的Ubuntu內核是SMP? – m0skit0 2012-04-10 15:55:07

回答

17

有在你的代碼的兩個問題:

  1. 你錯過了你的編譯的parallel。所以它只使用1個線程。
  2. 您在j上遇到競賽狀況,因爲它在並行區域之外聲明。

首先,你需要parallel實際上使的OpenMP並行運行:

#pragma omp parallel for 

其次,你在並行區域之外聲明j。這將使它在所有線程中共享。所以所有線程都在並行區域內讀取和修改它。

因此,您不僅有競爭條件,而且所有失效導致的緩存一致性流量正在影響您的性能。

你需要做的就是讓j本地到每個線程。這可以通過以下任一方式完成:

  1. 在並行區域內聲明j
  2. 或添加private(j)到編譯:#pragma omp parallel for private(j)
    (在評論中指出的@ArjunShankar)

試試這個:

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 
+2

+1。另外:'#pragma omp parallel for private(j)'可以工作,而不是在本地範圍內聲明'j'。 – ArjunShankar 2012-04-10 16:53:59

相關問題