私はlinuxの下でC++で動作するmpi(openmpi 1.4.3)とpthreadsを使用するプログラムに取り組んでいます。posixスレッドとO3の最適化
mpiノードの中には、pthreadsで実装されたキューシステムがあります。 アイデアは、要素をキューに追加する単純な1つのスレッド、およびオブジェクトをピックアップしてそれらのジョブを実行する他の「動作中の」スレッドはほとんどありません(ロケット科学ではありません)。
要素を取り上げている私の作業スレッドの2つの例を考えてください。 -O3最適化が指定されていない限り、最初の例は正常に動作します。その場合、何も拾わずに無限にループし始めます。
while (true){
if (t_exitSignal[tID]){
dorun = false;
break;
}
//cout<<"w8\n";
//check if queue has some work for us
if (!frame_queue->empty()){
//try to get lock and recheck that queue no empty
pthread_mutex_lock(&mutex_frame_queue);
if (!frame_queue->empty()){
cout<<"Pickup "<<tID<<endl;
con = frame_queue->front();
frame_queue->pop();
t_idling[tID] = false;
pthread_mutex_unlock(&mutex_frame_queue);
break;
}
pthread_mutex_unlock(&mutex_frame_queue);
}
}
は今、私はqueue-> empthyをチェックする前にロックされたミューテックスgettimg除いて、この1、まったく同じコードを考えてみましょう。この作業は、すべてのレベルの最適化に適しています。
while (true){
if (t_exitSignal[tID]){
dorun = false;
break;
}
//cout<<"w8\n";
//try to get lock and recheck that queue no empty
pthread_mutex_lock(&mutex_frame_queue);
//check if queue has some work for us
if (!frame_queue->empty()){
cout<<"Pickup "<<tID<<endl;
con = frame_queue->front();
frame_queue->pop();
t_idling[tID] = false;
pthread_mutex_unlock(&mutex_frame_queue);
break;
}
pthread_mutex_unlock(&mutex_frame_queue);
}
は、念のために、これは私が他のスレッドから
pthread_mutex_lock(&mutex_frame_queue);
//adding the same contianer into queue to make it available for threads
frame_queue->push(*cursor);
pthread_mutex_unlock(&mutex_frame_queue);
をキューに移入する方法で違いを作る私の質問は:私は-O3オプションを指定してコンパイルし、なぜ、なぜ、コードストップの最初の例では、作業しますか? キューイングシステムに関する他の提案はありますか?
ありがとうございます!
解決策:これは私が最後に思いつくものです。上記のいずれの方法よりもはるかにうまくいくと思われます。 (念の誰かに興味を持って;)
while (true){
if (t_exitSignal[tID]){
dorun = false;
break;
}
//try to get lock and check that queue no empty
pthread_mutex_lock(&mutex_frame_queue);
if (!frame_queue->empty()){
con = frame_queue->front();
frame_queue->pop();
t_idling[tID] = false;
pthread_mutex_unlock(&mutex_frame_queue);
break;
}else{
pthread_cond_wait(&conf_frame_queue, &mutex_frame_queue);
pthread_mutex_unlock(&mutex_frame_queue);
}
}
は、私は、キューが空であるかどうかをチェックするときに、命令の順序についての仮定に基づいてバグを見ている推測している
pthread_mutex_lock(&mutex_frame_queue);
//adding the same contianer into queue to make it available for threads
frame_queue->push(*cursor);
//wake up any waiting threads
pthread_cond_signal(&conf_frame_queue);
pthread_mutex_unlock(&mutex_frame_queue)