2012-01-27 9 views
1

OpenMPを使用して誤った共有が発生していると思います。それを特定して修正する方法はありますか?OpenMP False Sharing

私のコードは次のとおりhttps://github.com/wchan/libNN/blob/master/ResilientBackpropagation.hppシングルスレッド1つのコアバージョンに比べ4コアCPUを使用してライン36

追加の性能がわずか10%が得られました。 NUMA 32物理(64仮想)CPUシステムを使用する場合、CPU使用率は約1.5コアで止まります。これは誤った共有の直接的な症状であり、拡大縮小できないと思います。

また、インテル®VTuneプロファイラーで実行しようとしましたが、ほとんどの時間は "f()"および "+ ="機能に費やされています。私はこれが合理的だと信じて、なぜ私がそのようなスケーリングを得ているのかを実際に説明していません...

アイデア/提案はありますか?

ありがとうございました。

+3

偽の共有は減少しませんCPU使用率。これは単にキャッシュミスのトンを引き起こします。 – Mysticial

+0

@ミステリ​​ー - スケジューラがページを所有していたプロセッサ上のすべてのスレッドをスケジューリングして過度に移行しないようにNUMAでスケジューリングしていたとします。 – Flexo

+0

@awoodlandこれは確かに可能です。すべてをメモリに接近させることの別の結果にもかかわらずです。 (あなたが私のUNに2番目の「私」を残してから、私はあなたのpingを手に入れませんでした) – Mysticial

答えて

2

スレッドIDに基づいて配列を明示的に索引付けするのではなく、削減を使用します。そのアレイは実質的に誤った共有を保証します。

すなわちこれでこの

#pragma omp parallel for 
    clones[omp_get_thread_num()]->mse() += norm_2(dedy); 

for (int i = 0; i < omp_get_max_threads(); i++) { 
    neural_network->mse() += clones[i]->mse(); 

を置き換える:確かに知っているの

#pragma omp parallel for reduction(+ : mse) 
    mse += norm_2(dedy); 

neural_network->mse() = mse; 
1

一つの方法は、cachegrindのようなツールを使用してキャッシュの統計を見ている:

valgrind --tool=cachegrind [command] 
+0

cachegrindはマルチスレッドプログラムをうまく扱いますか? – Flexo

+0

はいこれは私が考えていたものですスレッドプロファイリングツール+1 – pyCthon

+0

複数のスレッドをサポートしていますが、valgrindは独自の内部スケジューラを使用してスレッドの実行をシーケンシャル化しています。私はここではキャッシュグリンディッドが良い選択だとは思わない。 – janjust