※ ChatGPTを利用し、要約された質問です(原文:OpenMPのことで悩んでいます)
OpenMPで配列のリダクションを効率的に行う方法
このQ&Aのポイント
現在、OpenMPを用いてOpenCVのライブラリを並列実行可能な形にしていますが、配列のリダクションを行う部分で問題が発生しています。
データアクセスの競合を防ぐために「#pragma omp critical」という方法を試しましたが、処理速度が200倍遅くなってしまい、使い物になりません。
より効率的な配列のリダクション方法を知りたいです。OpenMPで配列のリダクションをする際の定石があれば教えていただきたいです。
現在、OpenMPを用いてOpenCVのライブラリを並列実行可能な形にしています。
その中で、配列のリダクションを行う場所があるのですが、その部分をどう書き換えればいいのか悩んでいます。
for( i = 0; i < height; i++ )//画像の高さ
{
for( j = 0; j < width; j++ )//画像の幅
{
if( image[i * step + j] != 0 ) //エッジ抽出後の画像データ
for(int n = 0; n < numangle; n++ )
{
int r = cvRound( j * tabCos[n] + i * tabSin[n] ); //極座標空間への変換
r += (numrho - 1) / 2;
int index = (n + 1) * (numrho + 2) + r + 1;
//#pragma omp critical
//{
accum[index]++; //極座標に対応する配列accumへの軌跡の投票
//}
}
}
}
上がそのコードです。配列accumの要素をインクリメントする際に、データアクセスの競合が起こってしまいます。
その部分の上に「#pragma omp critical」と入れればアクセスの競合は防げるのですが、速度が200倍程度遅くなってしまい、使い物になりません。
なんとか配列の要素に対するリダクション処理を行いたいです。
OpenMPで配列のリダクションをする際の定石等あれば教えていただきたいです。
お礼
ありがとうございます。 私の方でもいろいろとやってみたのですが、やはりアルゴリズムの大幅な変更が必要だという結論になりました。 OpenMPにはアドレス単位のアトミック演算がないというのが痛いですね・・・。