6

簡単な Producer/Consumer プログラムを作成する実験を試みました。それらは別々のスレッドで実行されます。プロデューサはいくつかのデータを生成し、コンシューマは別のスレッドでそれを取得します。私が達成したメッセージング遅延は、約 100 ナノ秒です。これが合理的かどうか、またははるかに高速な実装があるかどうか、誰か教えてもらえますか?

私はロックを使用していません...単純なメモリカウンターです。私の実験はここで説明されています:

http://tradexoft.wordpress.com/2012/10/22/how-to-move-data-between-threads-in-100-nanoseconds/

基本的に、消費者はカウンターがインクリメントされるのを待ってから、ハンドラー関数を呼び出します。したがって、実際には多くのコードはありません。それでも100nsかかるのには驚きました。

コンシューマーは次のようになります。

 void operator()()
    {
      while (true)
      {
        while (w_cnt==r_cnt) {};
        auto rc=process_data(data);
        r_cnt++;
        if (!rc)
          break;
      }
    }

プロデューサは、利用可能なデータがある場合、単純に w_cnt をインクリメントします。

もっと速い方法はありますか?

4

2 に答える 2

6

レイテンシーは、スピンロック自体ではなく、オペレーティングシステムがコンテキスト切り替えをスケジュールする方法の結果であると思いますが、それについて多くのことができるとは思えません。

ただし、リングバッファを使用すると、一度により多くのデータを移動できます。1つのスレッドが書き込み、1つのスレッドが読み取りを行う場合、ロックなしでリングバッファを実装できます。基本的には同じスピンロックアプローチ(まで待機tailidx != headidx)ですが、プロデューサーは、コンシューマーに切り替えられる前に、複数の値をバッファーに送り込むことができます。これにより、全体的なレイテンシーが改善されるはずです(ただし、単一値のレイテンシーは改善されません)。

于 2012-10-22T22:39:13.530 に答える
3

スレッドが異なるコアで実行されている場合、あるスレッドから別のスレッドに「メッセージを送信」する最速の方法は、write barrier(sfence)です。

あるメモリ ロケーションに書き込む場合、実際には、メイン メモリ ロケーションではなく、プロセッサの書き込みバッファに書き込みます。書き込みバッファは、プロセッサによって定期的にメイン メモリにフラッシュされます。また、命令の並べ替えが発生すると、書き込み命令が遅延する可能性があります。メインメモリへの実際の書き込みが発生すると、キャッシュコヒーレンシプロトコルが機能し、メモリ位置の更新について別のプロセッサに「通知」します。その後、別のプロセッサがキャッシュ ラインを無効にし、別のスレッドが変更を確認できるようになります。

ストア バリア フォース プロセッサが書き込みバッファをフラッシュし、命令の並べ替えを禁止すると、プログラムは 1 秒あたりにより多くのメッセージを送信できるようになります。

于 2012-10-23T10:02:34.623 に答える