2012-10-16 31 views
1

我有下面的代碼,我實現了一個明確的任務版本:上執行的代碼的性能1個線程奇特的性能:1個線程執行不是多線程更好

int waves = N_a + N_b +1; /*considering N_a == N_b */ 
#pragma omp parallel firstprivate(a, gap, waves) private(temp, wave, ii, i) shared(np, mp, elements) 
    { 
#pragma omp master 
     { 
      for(wave = 0; wave < waves; ++wave) { 
       // 0 <= wave < n-1 
       if(wave < N_a-1) { 
        elements = wave+1; 
        np = wave+1; 
        mp = 0+1; 
       } 
       // n-1 <= wave < m 
       else if(wave < N_b) { 
        elements = N_a; 
        np = N_a-1+1; 
        mp = wave-(N_a-1)+1; 
       } 
       // m <= wave < m+n-1 
       else { 
        elements = N_a-1-(wave-N_b); 
        np = N_a-1+1; 
        mp = wave-(N_a-1)+1; 
       } 

       for(ii = 0; ii < elements; ii+=chunk) { 
        min = MIN(elements,ii + chunk); 
#pragma omp task firstprivate(ii, np, mp, chunk, elements) 
        { 
         for (i = ii; i < min; i++) 
         { 

         temp[0] = H[(np-i)-1][(mp+i)-1] + similarity(seq_a[a][(np-i)-1],seq_b[a][(mp+i)-1]); 
         temp[1] = H[(np-i)-1][(mp+i)]-gap; 
         temp[2] = H[(np-i)][(mp+i)-1]-gap; 
         temp[3] = 0; 
         H[(np-i)][(mp+i)] = find_array_max(temp,4); 
         } 
        } // task 
       } //for loop 
#pragma omp taskwait 
      } 
     } 

    } 

奇怪比2,4,8和16線要好得多。只有一個平行區域,並且我已經爲內部for循環條帶挖掘,以便每個「塊」元素都將有助於創建任務。

我堅持創建一個任務實現,因爲這個元素的值會不斷變化,我覺得代碼有可能通過高效的任務實現來抵消非結構化並行。

我想在英特爾xe12版本編譯器上。以下是我觀察樣本塊大小的讀數:256和N_A = N_B = 4096:

1線程:1.237560 2線程:7.223232 4線程:4.579173 8線程:3.663661 16個線程:4.425525

我注意到gcc編譯器的一個類似的行爲。有人可以請爲什麼使用1線程的代碼比多線程做得更好。 我也看到N_a = N_b = 1024,2048和8192的相似結果。

謝謝。

+0

您可以提供一個小型自包含示例來玩嗎? – Massimiliano

+0

你應該檢查[這裏](http://stackoverflow.com/questions/12320754/why-is-it-that-restricting-multithreaded-applications-to-one-core-make-it-run-fa/12461163# 12461163)瞭解性能。 – Raj

+0

「1個線程」是指在OMP_NUM_THREADS = 1下運行,還是在未啓用OpenMP的情況下編譯? –

回答

2

您的所有代碼都由#pragma omp master保護,它只允許主線程運行所有計算。您必須刪除該編譯指示(或者是否有任何理由?)才能看到至少一些縮放。