2011-11-09 143 views
0

所以我有一點麻煩找出並行使用openmp的這些循環的最佳方式。我猜,最大速度可達將來自並行環路中間像我在這裏做的:使用openmp嵌套for循環和內部函數的問題

for(i = 0; i < m/16*16; i+=16){ 
    #pragma omp parallel for 
     for(j = 0; j < m; j++){ 

      C_column_start = C+i+j*m; 

      c_1 = _mm_loadu_ps(C_column_start); 
      c_2 = _mm_loadu_ps(C_column_start+4); 
      c_3 = _mm_loadu_ps(C_column_start+8); 
      c_4 = _mm_loadu_ps(C_column_start+12); 

      for (k=0; k < n; k+=2){ 

       A_column_start = A+k*m; 

       a_1 = _mm_loadu_ps(A_column_start+i); 
       a_2 = _mm_loadu_ps(A_column_start+i+4); 
       a_3 = _mm_loadu_ps(A_column_start+i+8); 
       a_4 = _mm_loadu_ps(A_column_start+i+12); 

       b_1 = _mm_load1_ps(A_column_start+j); 

       mul_1 = _mm_mul_ps(a_1, b_1); 
       mul_2 = _mm_mul_ps(a_2, b_1); 
       mul_3 = _mm_mul_ps(a_3, b_1); 
       mul_4 = _mm_mul_ps(a_4, b_1); 

       c_4 = _mm_add_ps(c_4, mul_4); 
       c_3 = _mm_add_ps(c_3, mul_3); 
       c_2 = _mm_add_ps(c_2, mul_2); 
       c_1 = _mm_add_ps(c_1, mul_1); 

       A_column_start+=m; 

       a_1 = _mm_loadu_ps(A_column_start+i); 
       a_2 = _mm_loadu_ps(A_column_start+i+4); 
       a_3 = _mm_loadu_ps(A_column_start+i+8); 
       a_4 = _mm_loadu_ps(A_column_start+i+12); 

       b_1 = _mm_load1_ps(A_column_start+j); 

       mul_1 = _mm_mul_ps(a_1, b_1); 
       mul_2 = _mm_mul_ps(a_2, b_1); 
       mul_3 = _mm_mul_ps(a_3, b_1); 
       mul_4 = _mm_mul_ps(a_4, b_1); 

       c_4 = _mm_add_ps(c_4, mul_4); 
       c_3 = _mm_add_ps(c_3, mul_3); 
       c_2 = _mm_add_ps(c_2, mul_2); 
       c_1 = _mm_add_ps(c_1, mul_1); 

      } 


      _mm_storeu_ps(C_column_start, c_1); 
      _mm_storeu_ps(C_column_start+4, c_2); 
      _mm_storeu_ps(C_column_start+8, c_3); 
      _mm_storeu_ps(C_column_start+12, c_4); 

     } 

    } 

然而,目前這讓我幾乎沒有加速。任何提示都會很棒。我已經停留了一段時間了。

+1

您是否嘗試並行化外部循環? –

+0

我做到了。它也不給我任何加速。 –

回答

2

首先,你確定循環是可並行的嗎?值爲m的範圍是多少?當所有三個嵌套循環都可並行化並且足夠大(至少16個左右)時,那麼並行化最外面的循環將是最有利的。平行內環可能有omp parallel for嚴重的分叉連接開銷。

對於低增速,這裏是一些清單:

  1. 你確定所有內核被利用?檢查一種任務管理器。由於除了omp parallel for的隱含屏障之外沒有同步,所以應該使用所有內核。
  2. m龐大的數字?而且,計算長度是多少?如果m巨大而計算量很小,則由於omp parallel for而導致的並行開銷可能會抵消並行化的好處。並行化內部循環時,行程計數(例如,m)不應該很大。
  3. False sharing可能是一個原因。如果您的代碼修改了大量內存,則可能會導致錯誤共享,並且加速可能會受到影響。