2012-08-27 42 views
4

我想這個並行化功能,但我是新開放的MP,我會很感激,如果有人可以幫助我:OpenMP C++ - 如何並行化這個函數?

void my_function(float** A,int nbNeurons,int nbOutput, float* p, float* amp){ 
    float t=0; 
    for(int r=0;r<nbNeurons;r++){ 
     t+=p[r]; 
    } 

    for(int i=0;i<nbOutput;i++){ 
     float coef=0; 
     for(int r=0;r<nbNeurons;r++){ 
     coef+=p[r]*A[r][i]; 
     } 
    amp[i]=coef/t; 
    } 
} 

我不知道如何正確地進行並行化因雙循環,目前,我只想到做一個: #pragma omp parallel for reduction(+:t)

但我認爲這不是通過openMp更快地獲得計算的最佳方式。

在此先感謝,

+0

不要讓雙循環嚇跑你。你也可以在OpenMP上使用'pragma'。 – Mysticial

+1

並行化外部循環。 –

回答

8

首先:我們需要了解上下文。你的分析器在哪裏告訴你最花時間?

一般來說,粗粒度平行化效果最好,@Alex說:平行於外部for循環。

void my_function(float** A,int nbNeurons,int nbOutput, float* p, float* amp) 
{ 
    float t=0; 
    for(int r=0;r<nbNeurons;r++) 
     t+=p[r]; 

#pragma parallel omp for 
    for(int i=0;i<nbOutput;i++){ 
     float coef=0; 
     for(int r=0;r<nbNeurons;r++){ 
      coef+=p[r]*A[r][i]; 
     } 
     amp[i]=coef/t; 
    } 
} 

根據實際體積,它可能是有趣的計算在後臺t和移動劃分出並行循環:

void my_function(float** A,int nbNeurons,int nbOutput, float* p, float* amp) 
{ 
    float t=0; 
#pragma omp parallel shared(amp) 
    { 
#pragma omp single nowait // only a single thread executes this 
     { 
      for(int r=0;r<nbNeurons;r++) 
       t+=p[r]; 
     } 

#pragma omp for 
     for(int i=0;i<nbOutput;i++){ 
      float coef=0; 
      for(int r=0;r<nbNeurons;r++){ 
       coef+=p[r]*A[r][i]; 
      } 
      amp[i]=coef; 
     } 

#pragma omp barrier 
#pragma omp master // only a single thread executes this 
     { 
      for(int i=0; i<nbOutput; i++){ 
       amp[i] /= t; 
      } 
     } 
    } 
} 

注意未經測試的代碼。 OMP有時候會有棘手的語義,所以我可能錯過了那裏的'共享'聲明。儘管如此,探測器不會很快通知您。

+0

非常感謝您的回答,即使我修改了內部的值,是否可以並行化較高的循環?我的意思是這是一個+ =而不是一個簡單的感情=。謝謝。帕雷勒化是如此棘手...... – kuider

+0

那裏只有+ =和/ =專屬部分。係數不在線程中共享 – sehe

+1

我會 {在omp單一附註尾添加「nowait」,在函數的最後添加「#pragma barrier」。 } 或{「nowait」,但將「/ t」放回到並行for循環中。 } –