window7
Visual Studio2008
CPU core i7 960 3.20Hz
実装メモリ(RAM) 12.0GB
デスクトップ(HP)
OPENMP使用における疑問
以下のプログラムは 私が作った画像処理プログラムの一部です.
大まかに処理内容を言えば,画像1の対象画素と似ている位置を画像2から検出するプログラムです.
6重ループですがしていることは画像1の対象画素と似ている所を5x5ブロックで標準偏差などを求めて計算しています.
(しかしこれは処理時間が膨大です.なので画像2は+=2として飛ばしながら探索しています.
そして私はさらに速くならないかと考え,OPENMPを使うことにしました.)
結果として動作して速くなったのですが,NETの指示通りに組んだだけなので,上手く出来ている理由がぱっとしません.
OPENMPの挙動がよく分かってないというのが大きいのですが多重ループ関連は調べても「privateにしろ」以外あまりでない.
全てprivateにしたのですが,こんなんで出来るのでしょうか?
int k,j,jj,kk,n,m;
#ifdef _OPENMP
#pragma omp parallel for private(j,jj,kk,n,m,k,ty,tx,sy,sx,sum_t,sum2_t,sum_s,sum2_s,mean_t,mean2_t,mean_s,mean2_s,sigma2_t,sigma2_s,sdv_t,sdv_s,error,errormin,valueY_t,valueY_s,sdvY_t,sdvY_s)
#endif
/*画像1 */
for(k =0; k < height1; k++){
for(j=0; j < width1; j++){
/* 画像2 */
for(kk = 0; kk < height2; kk+=2){
for(jj = 0; jj < width2; jj+=2 ){
for(n=-2; n<2; n++){
ty = n+k;
sy = n+kk;
if(ty < 0) ty = 0;
if(sy < 0) sy = 0;
if(ty >= height1 ) ty = height1-1;
if(sy >= height2 ) sy = height2-1;
for(m = -2; m<2; m++){
tx = m+j;
sx = m+jj;
if(tx < 0) tx = 0;
if(sx < 0) sx = 0;
if(tx >= width1 ) tx = width1-1;
if(sx >= width2 ) sx = width2-1;
sum_t += img_target->Y[tx + ty*width1];
sum2_t += img_target->Y[tx + ty*width1]*img_target->Y[tx + ty*width1];
sum_s += img_source->Y[sx + sy*width2];
sum2_s += img_source->Y[sx + sy*width2]*img_source->Y[sx + sy*width2];
}
}
mean_t = sum_t/25;
mean2_t = sum2_t/25;
mean_s = sum_s/25;
mean2_s = sum2_s/25;
sigma2_t = mean2_t -mean_t*mean_t;
sigma2_s = mean2_s -mean_s*mean_s;
if(sigma2_t > 0){
sdv_t = sqrt(sigma2_t);
}else{
sdv_t = 0;
}
if(sigma2_s > 0){
sdv_s = sqrt(sigma2_s);
}else{
sdv_s = 0;
}
sdvY_t = sdv_t;
sdvY_s = sdv_s;
valueY_t = img_target->Y[k*width1+j];
valueY_s = img_target->Y[kk*width2+jj];
error = fabs(valueY_t -valueY_s) * 0.5 + fabs(sdvY_t -sdvY_s) * 0.5;
if(error < errormin){
errormin = error;
img_target_color->Y[k*width1+j] = img_target->Y[k*width1+j];
img_target_color->U[k*width1+j] = img_source->U[kk*width2 + jj];
img_target_color->V[k*width1+j] = img_source->V[kk*width2 + jj];
}
sum_t = 0;
sum_s = 0;
sum2_t =0;
sum2_s = 0;
error = 0;
}
}
errormin = 100000;
}
}