2013-06-09 19 views
8

pthreadsとUbuntu開発環境に基づいたスレッドで、最新のgccでmutexとメッセージの受け渡しに興味があります。このための良い一般的な問題は、各哲学者が左と右の隣人と共有するlhとrhフォークを使用する食堂の哲学者です。私はクアッドコアプロセッサを忙しくするために哲学者の数を99に増やしています。C++でのスレッドのパフォーマンス11

int result = try_lock(forks[lhf], forks[rhf]); 

上記のコードは私の哲学者は、彼らが一緒に食べる必要がある2本のフォークをつかむしようとすることができます。

// if the forks are locked then start eating 
    if (result == -1) 
    { 
     state[j] = philosophers::State::Eating; 
     eating[j]++; 
     if (longestWait < waiting[j]) 
     { 
      longestWait = waiting[j]; 
     } 
     waiting[j] = 0; 
    } else { 
     state[j] = philosophers::State::Thinking; 
     thinking[j]++; 
     waiting[j]++; 
    } 

上記のコードは、彼らが2本のフォークを確保するために管理している場合、私の哲学者が応じて食べたり考え進捗を監視します。

{ 
     testEnd te(eating[j]+thinking[j]-1); 
     unique_lock<mutex> lk(cycleDone); 
     endCycle.wait(lk, te); 
    } 

上記のコードは、哲学者は、新たな試みを作るために自由であるこの時間の後に選択を完了するために、すべての哲学者を待ち:

if (philosophers::State::Eating == state[j]) 
    { 
     state[j] = philosophers::State::Thinking; 
     forks[lhf].unlock(); 
     forks[rhf].unlock(); 
    } 

私は哲学者や移動を監視し、メインスレッドを持っていますそれらを1つのサイクルから次のサイクルに移して、約10秒間食べてできるだけ多く考えることができます。 結果は約9540サイクルあり、飢えている哲学者や食べたくなる人が多く、思考時間が多いです!だから私は、リリースと考えるように食べるの哲学者を必要とするのではなく、非常に小さな休憩後に同じフォークをGABによって食べオーバーを防止するために、飢餓や長すぎる待ってから、私の哲学者を保護するので、私はより多くのロジックを追加する必要があります。

// protect the philosopher against starvation 
    if (State::Thinking == previous) 
    { 
     result = try_lock(forks[lhf], forks[rhf]); 
    } 

今私は9598サイクルを持っていて、すべての哲学者が食べるのに比較的等しいシェア(2620 - 2681)を得て、最長で14秒待って考えます。しかし私は満足していないので、今私はミューテックスとロックをすべて取り除き、偶数サイクルで食べる哲学者と奇妙なサイクルで食べる奇妙な哲学者とを単純にします。私は

while (counter < counters[j]) 
{ 
    this_thread::yield(); 
} 

は、グローバルサイクルカウンタを使用して何回も食べるか考えてから哲学を防ぎ哲学を同期する簡単な方法を使用します。同じ時間と哲学者は、36400回の食事で約73543サイクルを管理し、3サイクル以上を待っています。だから、ロックなしの私の単純なアルゴリズムは、高速であり、さまざまなスレッド間の処理のより良い分布を持っています。

誰もがこの問題を解決する良い方法を考えることができますか?私は、複数のスレッドを持つ複雑なシステムを実装すると、従来のミューテックスとメッセージパッシングの手法に従えば、システムのさまざまなスレッドで必要以上に不均衡な処理が遅くなることに懸念しています。

+3

ランダムに生成されたものよりも、最適であることが知られている手作業による同期スケジュールが勝利します。すばらしいです。問題はどこだ? –

+1

C++ 1yの 'std :: hemlock'プロポーザルは、この問題を一度解決しなければなりません。 –

+0

これはC++ 11自体とは何の関係もないようです。 –

答えて

2

これは、C++のスレッディングの問題を探求する興味深い方法です。

私は私は伝統的なミューテックス、メッセージパッシング技術に従えば私が必要以上に遅く、可能アンバランス処理で終わるであろうことを、複数のスレッドを有する複雑なシステムを実装するときことを恐れ:特定点に対処するため

私のシステムのさまざまなスレッド。

残念ながら、私があなたに与える最良の答えは、これが十分に確立された恐怖であるということです。スケジューリングと同期のコストはアプリケーションに固有ですが、これは大規模なシステムを設計する際の工学的決定になります。まず第一に、スケジューリングはNP-Hard(http://en.wikipedia.org/wiki/Multiprocessor_scheduling)ですが、近似値は良好です。

具体的な例を挙げると、あなたが提示した結果に基づいて一般的な結論を導き出すことは難しいと思います。粗い粒界同期と微細粒界の同期のトレードオフです。これはよく研究された問題であり、いくつかの研究が役に立つかもしれません(例えばhttp://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=744377&tag=1)。

これは全体として、解決したい問題、オペレーティングシステム、およびハードウェアに固有のエンジニアリング問題に触れています。

関連する問題