0

私の質問は、シミュレーションを実際にはパフォーマンスを低下させないように、マルチスレッドを以下のように正しく設計する方法です。効率的な方法でシミュレーションのループ内でマルチスレッドが可能ですか?

class MyClass 
{ 
private: 
    int *data1 = new int[ARRAY_SIZE](); 
    int *data2 = new int[ARRAY_SIZE](); 

public: 
    void fillData(); //any function that fills the inner data 
    void processData(const int iteration); 
} 

シミュレーションの各反復、4:

は、あなたが(500メガバイトごとの周りに)大きな配列のカップルを保持MyClassというクラス、およびそのようなアレイを用いて情報を処理する機能を持っていると仮定しますMyClassのインスタンスが処理されます。私の理想的な世界では、このようなインスタンスのそれぞれを1つのスレッドに渡し、次に各スレッドの内部に渡すことです。instance.processData()を呼び出してください。 #include <thread>を使用すると、それは次のようになります。

int main() 
{ 
    MyClass inst1,inst2, inst3, inst4; 

    //<----- here you would have code that fills the arrays inside each instance of MyClass 

    for(int iteration=0; iteration<MAX_ITERATIONS; iteration++) 
    { 
     std::thread t1(&MyClass::processData, &inst1, iteration); 
     std::thread t2(&MyClass::processData, &inst2, iteration); 
     std::thread t3(&MyClass::processData, &inst3, iteration); 
     std::thread t4(&MyClass::processData, &inst4, iteration); 

     t1.join(); 
     t2.join(); 
     t3.join(); 
     t4.join(); 
    } 

    return 0; 
} 

私は反復ごとのスレッドにMyClassインスタンスを派遣していた理由は、各インスタンスのprocessData終了した後、私はそれぞれのデータの結果との間に比較を行うことです繰り返しごとにインスタンス

問題は、記述されているコードが実際には非マルチヒットバージョンよりも非常に遅いことです。それで問題は次のようになります。私は何が間違っているのですか?それを改善する方法はありますか?各繰り返しの最後に各インスタンスの処理の結果を比較しなければならないと考えていますか?

PS1:私は絶対にprocessDataに含まれるプロセスをパラレル化できません。これは100%の問題です。

PS2:実際のコードに関連するものはそれ自体では公開できませんが、私が上で書いたスニペットを参考にして実際のコンパイル可能な例にすることができれば助かります。私はそれがなければ十分に明確な点があるかもしれないと思うが。

+1

ループ内のスレッドのオーバーヘッドを行うことは非常に非効率的である。 – franji1

+0

「PS2」に関して、はい、[mcve]を提供してください。特に、このようなコードを一切持たずに、「反復ごとに各インスタンスのデータ結果間の*比較」に関するあなたの発言を解決することは困難です。これはパフォーマンスに関するものなので、MCVEの改善が実際のコードに変換されるような例でも、同様のパフォーマンス特性が必要です。 – Zulan

答えて

0

パフォーマンスが低下するのは、スレッドではなく4つのスレッドを使用している可能性があります。確認する基本的な事項は次のとおりです。

  • パラレル化のオーバーヘッド:スレッドの作成と同期のコストです。 processDataで行われる作業量が少なく、繰り返し回数が多い場合は、スレッドの作成コストと廃棄コストが問題になります。障壁、ロック、アトミック操作など、processData()内に同期構造がある場合、これらはスローダウンの原因となる可能性があります。

  • Thrashing:1つのスレッドが実行されるとき、複数のスレッドが実行されているときよりも、アクティブメモリのセット(書き込まれ、読み込まれるメモリ)が非常に小さいことがよくあります。これは、ずっと多くのキャッシュミス(すなわち、複数のスレッドがL2およびL3キャッシュを共有することに起因する)を招く可能性がある。プログラムがシステム上の物理メモリ(スワッピング)を超えている場合、複数のスレッドがページスラッシングを引き起こしますが、スレッドスレッドはページスラッシングを引き起こします。

  • リソースの競合:プロセスがディスクやネットワークへの読み取り/書き込みを行っている場合は、そのリソースでスラッシングするような経験をしている可能性があります。

  • False Sharing:これは、スレッドが同じキャッシュライン上の異なる場所に書き込みおよび読み取りを行うため、キャッシュラインが無効化され、リフレッシュされると計算が繰り返しスローされます。より良い診断を可能にする

質問:

  1. 逐次実行する反復あたりの実行の合計ウォールクロック時間はどのくらいですか?

  2. 4スレッドの場合、反復ごとの壁時計の合計時間はどのくらいですか?

  3. は、このシステムの物理仕様(すなわち、それはどのように多くの物理的および論理コアを持っているんは何processData()(例えば、ソート、スパース線形代数、密な線形

  4. 操作/アルゴリズムのどのようなタイプでありますそれはどのくらいの物理メモリを持っていないキャッシュは、)どのように大きなですか?

  5. 行っているどのように多くの反復?

関連する問題