2011-11-09 4 views
0

그래서 openmp를 사용하여 이러한 루프를 병렬 처리하는 가장 좋은 방법을 찾지 못했습니다.중첩 된 for 루프 및 내장 함수로 openmp 사용시 문제가 발생했습니다.

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입니까? 세 중첩 루프를 병렬화하고 m 충분히 크면

는 (적어도 16 정도 말), 그 가장 바깥 고리 병렬화 것이 가장 유용 할 것이다. 내부 루프를 병렬 처리하면 심각한 분기 - 연결 오버 헤드가 omp parallel for에서 발생할 수 있습니다.

  1. 당신이 모든 코어를 활용하고 있는지 위치 : 낮은 속도 향상을 위해

    는 여기에 몇 가지 체크리스트입니까? 일종의 작업 관리자를 확인하십시오. 암시 적 장벽 omp parallel for을 제외한 동기화가 없으므로 모든 코어를 사용해야합니다.

  2. m은 큰 숫자입니까? 그리고, 계산 길이는 얼마입니까? m이 크고 계산량이 적 으면 omp parallel for에 의한 병렬 오버 헤드가 병렬화의 이점을 상쇄 할 수 있습니다. 내부 루프를 병렬화하면 트립 횟수 (예 : m)가 커질 수 없습니다.
  3. False sharing이 원인 일 수 있습니다. 코드가 많은 메모리를 수정하면 잘못된 공유가 발생할 수 있으며 속도가 빨라질 수 있습니다.