8

D プログラミング言語ランタイムの保守担当者に、メモリ アロケータ/ガベージ コレクタが通常の OS クリティカル セクションの代わりにスピンロックを使用するように何度か提案しました。これはあまり普及していません。スピンロックの方が優れていると私が考える理由は次のとおりです。

  1. 少なくとも私が行った合成ベンチマークでは、メモリ アロケータ/GC ロックの競合がある場合、OS クリティカル セクションよりも数倍高速です。編集:経験的に、スピンロックを使用しても、シングルコア環境では測定可能なオーバーヘッドさえありませんでした。おそらく、メモリアロケーターでロックを短時間保持する必要があるためです。
  2. メモリの割り当てや同様の操作には、通常、タイムスライスのごく一部、さらにはコンテキスト スイッチにかかる時間のごく一部しかかからないため、競合が発生した場合にコンテキストを切り替えるのはばかげています。
  3. 問題の実装でのガベージ コレクションは、とにかく世界を停止します。コレクション中に回転することはありません。

メモリ アロケータ/ガベージ コレクタの実装でスピンロックを使用しない正当な理由はありますか?

4

6 に答える 6

3
  1. 明らかに、スピンロックの最悪の場合の動作はひどいものです (OS スケジューラーは 30 個の CPU バウンド スレッドを認識するだけなので、それらすべてにいくらかの CPU 時間を与えようとします。そのうち 29 個は、ロックを保持しているスレッドがスリープしている間、狂ったようにスピンします)。したがって、可能であればそれらを避ける必要があります。このため、スピンロックにはユーザー空間のユースケースがないと主張する私よりも賢い人はたくさんいます。

  2. システム ミューテックスは、スレッドをスリープ状態にする (または実際にあらゆる種類のシステム コールを行う) 前に少しスピンする必要があるため、競合が発生した場合でも、スピンロックとまったく同じように動作することがあります。

  3. アロケーターは、多くの場合、ロックを使用してページをスレッドに割り当てるだけで、実質的にロックの競合を排除できます。各スレッドは、独自のページを分割する役割を果たします。N回の割り当てごとに1回だけロックを取得することになり、Nを好きなように構成できます。

2 と 3 は、合成ベンチマークでは効果的に対抗できない強力な議論であると考えています。実際のプログラムのパフォーマンスが低下することを示す必要があります。

于 2009-12-15T22:05:07.773 に答える
2

メモリ アロケータ/ガベージ コレクタの実装でスピンロックを使用しない正当な理由はありますか?

一部のスレッドがコンピューティング バウンド (CPU バウンド) であり、他のスレッドがメモリ アロケーター バウンドの場合、スピンロックを使用すると CPU サイクルが必要になります。CPU サイクルは、コンピューティング バウンド スレッドによって使用されたり、他のスレッドに属するスレッドによって使用されたりする可能性があります。プロセス。

于 2009-12-15T22:12:24.030 に答える
2

スピンロックは、CPU/コアが 1 つしかないシステム、またはより一般的には競合の多い状況 (ロックで待機しているスレッドが多数ある場合) ではまったく価値がありません。

于 2009-12-15T21:49:52.890 に答える
2

とにかく、Windows では、クリティカル セクション オブジェクトには既にこれを行うオプションがあります ( http://msdn.microsoft.com/en-us/library/ms682530.aspx ):

スレッドは、InitializeCriticalSectionAndSpinCount または SetCriticalSectionSpinCount 関数を使用して、クリティカル セクション オブジェクトのスピン カウントを指定します。スピンとは、スレッドがロックされているクリティカル セクションを取得しようとすると、スレッドがループに入り、ロックが解放されているかどうかを確認し、ロックが解放されていない場合はスレッドがスリープ状態になることを意味します。シングル プロセッサ システムでは、スピン カウントは無視され、クリティカル セクションのスピン カウントは 0 (ゼロ) に設定されます。マルチプロセッサ システムでは、クリティカル セクションが使用できない場合、呼び出しスレッドは、クリティカル セクションに関連付けられているセマフォで待機操作を実行する前に、dwSpinCount 回スピンします。スピン操作中にクリティカル セクションが解放されると、呼び出しスレッドは待機操作を回避します。

うまくいけば、他のプラットフォームがまだ続いていなければ、それに続くでしょう。

于 2009-12-15T21:56:55.583 に答える
0

同意するかどうかはわかりません。メモリの割り当てには非常に長い時間がかかる可能性があるためです(すべてのメモリを事前に割り当ててから再発行する場合にのみそうなります)..マルチギグヒープサイズで同じ割り当てと割り当て解除を実際に試す必要があります何百万ものエントリがあり、多くのアプリケーションが割り当てクリティカルセクションにヒットし(スレッドではなくアプリケーションに注意)、十分なメモリからのディスクのトラッシング/スワッピングがあります。また、割り当て中にディスクスワッピングの問題が発生する可能性があり、ディスク要求を待機するスピンロックを実行することは確かに適切ではありません。

そして、Cyber​​ShadowがシングルスレッドCPUで述べたように、オーバーヘッドのある通常のロックに移行することになります。これで、言語はすべてシングルスレッドの多くの組み込みCPUで実行できます。

また、インターロックされた交換を回避できる場合は、それが最善です(ただし、ロックレスであるにもかかわらず、CPUを停止し、マルチコアメモリのLOCK#を上げます)が、ほとんどのロックはとにかくこれを使用します(ただし、さらに多くのことを行う必要があります)。ただし、ヒープの構造は通常、インターロックされたエクスチャンスでは不十分であり、クリティカルセクションを作成することになります。GCを備えた(世代別の)マークスイープナーサリーでは、ポインターのインターロックされた比較および追加として割り当てを行うことが可能であることに注意してください。これはCosmosC#OS GCに対して行い、スタック速度の割り当てに使用されます。

于 2010-01-10T08:30:31.217 に答える
0

Glasgow Haskell Compiler のガベージ コレクタのパフォーマンス バグの 1 つは非常に煩わしいため、「最後のコアのスローダウン」という名前が付けられています。これは、GC でのスピンロックの不適切な使用の直接的な結果であり、Linux ではそのスケジューラーが原因で悪化しますが、実際には、他のプログラムが CPU 時間を競合しているときに常にその影響が観察されます。

この効果はここの 2 番目のグラフで明らかであり、Haskell プログラムがわずか 5 コアを超えてパフォーマンスの低下を確認している最後のコア以外にも影響を与えていることがわかります。

于 2010-06-11T23:54:42.277 に答える