ミューテックスの特性#
ミューテックスを理解すると、さまざまなミューテックス属性を使い分けることができます。ミューテックス属性は、汎用性と効率性のトレードオフに関わるため、いくつか知っておくと便利です。適切なものを選ぶとパフォーマンスの向上につながります。ミューテックスの特性を次に説明します。表の要約も参照してください。
スケーラブル。一部のミューテックスはスケーラブルと呼ばれます。厳密に言えば、ミューテックスは実行を一度に 1 つのスレッドに制限するため、これは正確な名称ではありません。スケーラブルなミューテックスは、これ以上悪い結果にならないミューテックスのことです。待機中のスレッドが過剰にプロセッサー・サイクルとメモリー帯域幅を消費し、実際のワークを実行するスレッドの速度が低下する場合、ミューテックスはシリアル実行よりもパフォーマンスを低下させることがあります。スケーラブルなミューテックスは、競合が少ない場合はスケーラブルでないミューテックスよりも低速であることがあるため、このような場合はスケーラブルでないミューテックスのほうが適している場合があります。確実でない場合は、スケーラブルなミューテックスを使用してください。
公正。ミューテックスは公平でも不公平でもあります。公平なミューテックスは、スレッドが到達した順序でスレッドを通過させます。公平なミューテックスは、スレッドの飢餓状態を回避します。各スレッドには、それぞれ順番が回ってきます。ただし、不公正なミューテックスの方が、割り込みのためスリープしている次のタスクの代わりに実行中のタスクを先に処理するため、公正なミューテックスより高速な場合があります。
譲渡またはブロック。これはパフォーマンスに影響する実装の詳細です。長時間待機する場合、oneAPI スレッディング・ビルディング・ブロック (oneTBB) のミューテックスは、譲渡するかブロックします。ここで譲渡とは、進行が可能であるか繰り返しポーリングし、進行が不可能である場合、一時的にプロセッサーを譲り渡す [1] ことを意味します。ブロックとは、ミューテックスが進行を許可するまでプロセッサーを明け渡すことを意味します。待機時間が短い場合は譲渡ミューテックスを使用し、待機時間が長い場合はブロック・ミューテックスを使用します。
次は、ミューテックスの動作の概要です。
spin_mutexはスケーラブルではなく、不公平で、再帰的ではなく、ユーザー空間でスピンします。一見、不適切な機能のようですが、これは競合が軽量な場合は非常に高速です。多くのspin_mutexオブジェクトに競合状態を分散できるようなプログラム設計が可能な場合、他のミューテックスを使用してパフォーマンスを向上できます。ミューテックスの競合状態が重い場合は、使用中のアルゴリズムでパフォーマンスは向上しません。ロックの効率を改善するよりも、アルゴリズムの再設計を検討してください。mutexはspin_mutexと同様の動作をします。ただし、mutexは長時間の待機をブロックするため、高い競合に耐性があります。queuing_mutexはスケーラブルかつ公平で、再帰的ではなく、ユーザー空間でスピンします。スケーラビリティーと公平性が重要な場合に使用します。spin_rw_mutexとqueuing_rw_mutexは、spin_mutexとqueuing_mutexに似ていますが、さらにリーダーロックをサポートします。rw_mutexは、mutexに似ていますが、さらにリーダーロックをサポートします。speculative_spin_mutexとspeculative_spin_rw_mutexは、spin_mutexとspin_rw_mutexに似ていますが、ハードウェア・トランザクション・メモリーをサポートするプロセッサーでは投機的ロックも提供します。投機的ロックは、複数のスレッドが同じロックを取得することを可能にします。ただし、非投機的ロックとは異なる結果を生じる可能性がある「競合」が発生しない場合に限ります。これらのミューテックスは、低い競合率で動作する (主に投機的ロックモードで動作する) 場合、スケーラブルです。null_mutexとnull_rw_mutexは何も行いませんが、テンプレート引数として役立ちます。例えば、コンテナー・テンプレートを定義し、一部のインスタンスは複数のスレッドによって共有され、内部ロックが必要で他のインスタンスはスレッドに対してプライベートであり、ロックを必要としないことが判明しているとします。ミューテックス・タイプのパラメーターを受け取るテンプレートを定義できます。パラメーターは、ロックが必要な場合に実際のミューテックス・タイプのいずれかにすることができ、ロックが不要な場合はnull_mutexにできます。
ミューテックス |
スケーラブル |
公正 |
再帰 |
長い待ち時間 |
サイズ |
|---|---|---|---|---|---|
|
いいえ |
いいえ |
いいえ |
譲渡 |
1 バイト |
|
✓ |
いいえ |
いいえ |
ブロック |
1 バイト |
|
HW 依存 |
いいえ |
いいえ |
譲渡 |
2 キャッシュライン |
|
✓ |
✓ |
いいえ |
譲渡 |
1 ワード |
|
いいえ |
いいえ |
いいえ |
譲渡 |
1 ワード |
|
✓ |
いいえ |
いいえ |
ブロック |
1 ワード |
|
HW 依存 |
いいえ |
いいえ |
譲渡 |
3 キャッシュライン |
|
✓ |
✓ |
いいえ |
譲渡 |
1 ワード |
|
moot |
✓ |
✓ |
never |
空 |
|
moot |
✓ |
✓ |
never |
空 |