dポイントプレゼントキャンペーン実施中!

並列処理について。

画像imageの値が0より大きい場合に、managerを実行しますが、managerの計算時間が長いです。
そこで、4つのコアでpthreadにより、並列処理をさせたいんですが、
どのようにプログラムを書けばいいかすみませんが教えてください。
あるボクセルを計算中に、次のボクセルを計算するようなプログラム。。。

for (int z=0; z<32; z++){
 for (int y=0; y<32; y++){
  for (int x=0; x<32; x++){
   if(image(x,y,z) > 0){
    total += manager(x,y,z);
   }
  }
 }
}

A 回答 (2件)

念のために確認ですが、たとえばmanager(x,y,3)の計算結果がmanager(x,y,9)の計算に影響を与えるようなことはないのですよね?


影響する場合には仕事の分割が難しくなるので。

基本的な手順はこんな感じです。

1) メインスレッドは4つの子pthreadをpthread_createで起動します。それぞれのidを0~3とします。
2) 子pthreadはそれぞれ下記の計算を行います。total[]は大域変数という想定です。
for (int z=id*8; z<id*8+8; z++){
 for (int y=0; y<32; y++){
  for (int x=0; x<32; x++){
   if(image(x,y,z) > 0){
    total[id] += manager(x,y,z);
   }
  }
 }
}
3) メインスレッドは全ての子pthreadが終了するのをpthread_joinで待ちます。
4) メインスレッドでtotal[0~3]の結果を合計します。

子スレッドのidを指定するにはpthread_createの第4引数を使って工夫すればいいでしょう。
子スレッドの計算結果もpthread_exitを使ってメインスレッドに返す方法がありますが、void*型だからといってうっかりローカル変数へのポインタを使ったりすると予期しないことが起きます(この点はpthread_createの第4引数も同じ)。

zの範囲を4つのスレッドに分割した例を示しましたが、扱うデータの形式によっては別の分け方をしたほうがキャッシュミスが減って速くなるかもしれないです。
    • good
    • 0
この回答へのお礼

ご返事ありがとうございます。
managerの結果は相互に影響しないので、上の方法でやってみます。
データの中身によっては、ある断面(z=10)しか値がない場合があるので
x,yの範囲に分割してみまーす。

お礼日時:2009/12/03 10:31

どんな環境でやってますか?


OpenMP対応コンパイラ( VC++2005以降など)だとこんな書き方もできます

#pragma omp parallel for reduction(+:total)
for (int z=0; z<32; z++){
 for (int y=0; y<32; y++){
  for (int x=0; x<32; x++){
   if(image(x,y,z) > 0){
    total += manager(x,y,z);
   }
  }
 }
}
    • good
    • 0
この回答へのお礼

VC++2005 Academic Editionを使用しているので、
残念ながらOpenMPには未対応です。
しかし、OpenMPに関する情報ありがとうございます。

お礼日時:2009/12/24 15:12

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!