2017-05-18 9 views
1

私はNvidia Geforce GT 740MをOpenMPとclang-3.8コンパイラを使った並列プログラミングに利用しようとしています。OpenMPを使用してGPUにチームを配布するには?

CPUで並列処理すると、結果が得られます。しかし、GPUで処理すると、私の結果はほとんど乱数になります。

したがって、私はスレッドチームを正しく配布していないと思っていましたし、データ競合があるかもしれません。私はfor-loopsを別々にやらなければならないと思うが、間違いがどこにあるのか分からない。

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


int main(int argc, char* argv[]) 
    { 
    const int n =100; float a = 3.0f; float b = 2.0f; 
    float *x = (float *) malloc(n * sizeof(float)); 
    float *y = (float *) malloc(n * sizeof(float)); 

    int i; 
    int j; 
    int k; 

    double start; 
    double end; 
    start = omp_get_wtime(); 


    for (k=0; k<n; k++){ 
     x[k] = 2.0f; 
     y[k] = 3.0f; 
    } 


    #pragma omp target data map(to:x[0:n]) map(tofrom:y[0:n]) map(to:i) map(to:j) 
    { 

     #pragma omp target teams 
     #pragma omp distribute 
     for(i = 0; i < n; i++) { 

      #pragma omp parallel for 
      for (j = 0; j < n; j++){ 
       y[j] = a*x[j] + y[j]; 
     } 
    } 


} 


end = omp_get_wtime(); 

printf("Work took %f seconds.\n", end - start); 

free(x); free(y); 

return 0; 
} 

私のGPUのアーキテクチャには何かがあるかもしれません。そこで私はこれを追加している:あなたの助けに感謝をトピックにかなり新しい

GPU Information

イム、そう:)

答えて

0

はい、ここでのレースがあります。異なるチームが配列 'y'の同じ要素を読み書きしています。おそらく、あなたはこれのようなものが欲しいですか?

for(i = 0; i < n; i++) { 
    #pragma omp target teams distribute parallel for 
    for (j = 0; j < n; j++){ 
    y[j] = a*x[j] + y[j]; 
    } 
} 
+0

はい、それは私の問題を解決します、ありがとう。 しかし、 'y [j]'の代わりに 'y [i] [j]'という配列がある場合でも、私はまだ同じ問題を抱えています。 私はイテレータを変更する必要があると思います。 '+ 1'の代わりに、GPUブロックやそのようなものを繰り返し処理します。しかし、私は実際にどのように知りません。 – Atrobbus

+0

y [i] [j]という配列を持っているなら、レースフリーでなければなりません。あなたは変更されたプログラムを投稿できますか? –

+0

他の変数に起因するデータ競合があります。今それはすべて正常に動作します。 – Atrobbus

関連する問題