2016-04-27 10 views
-2

大きなベクトルのベクトル内積を計算するサブルーチンがあります。私はオープンMPを使ってそれを並列化しました。以下は私のコードです:負のスピードアップ並列化ベクトルベクトルのドットプロダクト

double scalarProd(double* vec1, double* vec2, int n){ 
double prod = 0.0; 
int chunk = 10; 
int i; 
//double* c = (double*) malloc(n*sizeof(double)); 

omp_set_num_threads(4); 

#pragma omp parallel 
{ 
    double pprod = 0.0; 
    #pragma omp for 
    for(i=0;i<n;i++) { 
     pprod += vec1[i]*vec2[i]; 
    } 

    #pragma omp critical 
    for(i=0;i<n;i++) { 
     prod += pprod; 
    } 
} 

return prod; }

ここで間違っていることを教えてもらえますか?

は、より多くの情報を追加する:私は

編集をマルチスレッドに初心者です。申し訳ありません、最初のタイマーはここにあります。

上記のサブルーチンは、私の関数ConjugateGradient()から複数回呼び出されます。私は今、以下のように私のConjugateGradient機能で時間計算コードを追加しました:

start_dotprod = omp_get_wtime(); 
rm_rm_old = scalarProd(rm,rm,MAT->ncols); 
    run_dotprod = omp_get_wtime() - start_dotprod; 
fprintf(timing,"Time taken by rm_rm dot product : %lf \n",run_dotprod); 

観察された結果:0.000007s パラレルバージョン:内積 シーケンシャルバージョンにかかった時間0.002110

は私がやっているの私のIntel I7ラップトップのLinux OSでgcc -fopenmpコマンドを使用して簡単にコンパイルしてください。私は現在、サイズの行列のn = 5000

を使用しています

私がダウンして全体的な収束が(80K周り回)達成されるまで同じ内積が複数回呼び出されるので、巨大な速度を取得しています。

私に改善を提案してください。私は何かがひどく間違っていると感じています。

ありがとうございます! :)

+0

CとC++は異なる言語です。使用していないタグを削除してください。 –

+2

Linux上で 'clock()'を使って実行時間を測定していますか? –

+0

ようこそ!スレッドの数、ハードウェア(CPU)、時間の測定方法、ベクトルサイズまた、[mcve]を入力してください。 – Zulan

答えて

-2

Prodはすべてのスレッドでプライベートですが、その値は以前の繰り返しに依存します。試してみてください:

prod [i] + = vec1 [i] * vec2 [i];

+1

いいえ、 'prod'は縮小変数です。 –

関連する問題