2013-04-11 58 views
0

我有一段代碼是我前一段時間編寫的。它的唯一目的是用openMP做實驗。但我最近將MacBook Pro Lion(2011年初)改裝爲MacBook Pro Mountain Lion(2013年初)。如果它有助於獲得更多其他信息的硬件,我會很樂意給予他們。 代碼在舊版本上運行良好,這意味着8個線程在我的處理器上獲得了100%(98%min)的負載。現在,在我的新機器上重新編譯的相同代碼只能獲得62%的最大處理器負載。即使我提出了線程。處理器負載均採用「istat pro」進行測量。使用不同版本的操作系統的OpenMP性能差異

我的問題是什麼會導致這種情況發生?

編輯:問題似乎解決,如果我刪除在#pragma omp parallel for shared(largest_factor, largest)。所以我得到#pragma omp parallel shared(largest_factor, largest) 但我仍然不明白爲什麼它的作品。

有問題的代碼:

#include <stdio.h> 
#include <omp.h> 

double fib(double n); 

int main() 
{ 
    int data[] = {124847,194747,194747,194747,194747, 
        194747,194747,194747,194747,194747,194747}; 
    int largest, largest_factor = 0; 



    omp_set_num_threads(8); 
    /* "omp parallel for" turns the for loop multithreaded by making each thread 
    * iterating only a part of the loop variable, in this case i; variables declared 
    * as "shared" will be implicitly locked on access 
    */ 
    #pragma omp parallel for shared(largest_factor, largest) 
    for (int i = 0; i < 10; i++) { 
      int p, n = data[i]; 

      for (p = 3; p * p <= n && n % p; p += 2); 
      printf("\n%f\n\n",fib(i+40)); 
      if (p * p > n) p = n; 
      if (p > largest_factor) { 
        largest_factor = p; 
        largest = n; 
        printf("thread %d: found larger: %d of %d\n", 
          omp_get_thread_num(), p, n); 
      } 
      else 
      { 
        printf("thread %d: not larger: %d of %d\n", 
          omp_get_thread_num(),  p, n); 
      } 
    } 

    printf("Largest factor: %d of %d\n", largest_factor, largest); 
    return 0; 
} 

double fib(double n) 
{ 
if (n<=1) 
{ 
    return 1; 
} 
else 
{ 
    return fib(n-1)+fib(n-2); 
} 
} 

回答

0

看不到正在使用的所有線程的主要原因是,每個線程需要不同的時間(由於遞歸函數或內循環),你只需要10次​​迭代。快速線程完成得很快,然後只剩下幾個線程運行。當你第一次運行你的代碼時,它會從100%開始,並且隨着快速線程完成和最後幾個慢速線程仍在運行而下降。如果將迭代次數更改爲100(並增加數據數組),您將會看到CPU使用率達到100%的時間更長。我在代碼中添加了一些定時打印輸出。

另外我認爲你有一個與你的共享變量的競爭條件,所以我把一個關鍵部分。

要回答你關於沒有「for」語句的代碼的問題那是在8個不同的線程上運行相同的代碼!而不是線程運行一個特定的迭代,他們每個運行所有10次迭代。這將不會比運行單個線程更快,甚至更慢。

最後,因爲每次迭代需要不同的時間,一般你應該使用「schedual(動態)」像這樣

#pragma omp parallel for shared(largest_factor, largest) schedule(dynamic) 

但是,因爲你只有10次迭代,我不認爲它會在多大的區別這個案例。下面是我的代碼,以瞭解發生了什麼:

#include <stdio.h> 
#include <omp.h> 

double fib(double n); 

int main() 
{ 
    int data[] = {124847,194747,194747,194747,194747, 
        194747,194747,194747,194747,194747,194747}; 
    int largest, largest_factor = 0; 

    omp_set_num_threads(8); 
    /* "omp parallel for" turns the for loop multithreaded by making each thread 
    * iterating only a part of the loop variable, in this case i; variables declared 
    * as "shared" will be implicitly locked on access 
    */ 
    #pragma omp parallel for shared(largest_factor, largest) 
    for (int i = 0; i < 10; i++) { 
      int p, n = data[i]; 
     double time = omp_get_wtime(); 
     for (p = 3; p * p <= n && n % p; p += 2); 
     printf("\n iteratnion %d, fib %f\n\n",i, fib(i+40)); 
     time = omp_get_wtime() - time; 
     printf("time %f\n", time); 

     if (p * p > n) p = n; 
     #pragma omp critical 
     { 
      if (p > largest_factor) {   
       largest_factor = p; 
       largest = n;  
       printf("thread %d: found larger: %d of %d\n", 
        omp_get_thread_num(), p, n); 
      } 
      else { 
       printf("thread %d: not larger: %d of %d\n", 
         omp_get_thread_num(),  p, n); 
      } 
     } 
    } 

    printf("Largest factor: %d of %d\n", largest_factor, largest); 
    return 0; 
} 

double fib(double n) { 
if (n<=1) { 
    return 1; 
} 
else { 
    return fib(n-1)+fib(n-2); 
} 
} 
+0

對'largest_factor'賦值和測試p'值是否更大時仍存在數據爭用條件。 – 2013-04-12 14:49:42

+0

我想我明白你的意思了。好的,我解決了這個問題。嘿,這是一個低窪的水果問題! – 2013-04-12 16:54:29

+0

我剛剛查看了一個經過測試的代碼,但空閒時間現在爲50到63%。但是你說它可能會變慢。我會試着瞭解你對代碼做了什麼。感謝您的幫助。 – 2013-04-15 17:36:46

相關問題