web-dev-qa-db-ja.com

ロックフリーのマルチスレッドは、実際のスレッドの専門家向けです

私は answer を読んでいた Jon Skeet が質問に与えた、そしてその中で彼はこれに言及した:

私の知る限り、ロックフリーのマルチスレッドは、実際のスレッドの専門家のためのものであり、私はその一人ではありません。

これを聞いたのは初めてではありませんが、ロックフリーマルチスレッドコードの書き方に興味があるなら、実際にそれを行う方法について話している人はほとんどいません。

したがって、私の質問は、スレッドなどについてできる限りすべてを学ぶこと以外に、ロックフリーのマルチスレッドコードを具体的に書くことを学ぶことから始めますか?.

乾杯

85
vdhant

ジョー・ダフィーの本:

http://www.bluebytesoftware.com/books/winconc/winconc_book_resources.html

また、これらのトピックに関するブログを書いています。

ローロックプログラムを正しく行うための秘Theは、特定のハードウェアの組み合わせでメモリモデルのルールがどのようなものであるかを、深いレベルで正確に理解することです。オペレーティングシステム、およびランタイム環境。

私は個人的には、InterlockedIncrementを超えて適切なローロックプログラミングを実行できるほどスマートではありませんが、もしあなたが素晴らしいなら、それを選んでください。メモリモデルの不変式の1つを誤って壊して見つけられないバグを導入しないように、コードに多くのドキュメントを残してください。

27
Eric Lippert

最近では「ロックフリースレッド」のようなものはありません。これは、コンピュータハードウェアが低速で高価だった前世紀の終わり頃に、学界などにとって興味深い遊び場でした。 Dekkerのアルゴリズム は常に私のお気に入りでしたが、現代のハードウェアはそれを放牧しました。もう機能しません。

これにより、2つの開発が終了しました。RAMとCPUの速度の格差の拡大。そして、チップメーカーがチップに複数のCPUコアを搭載する能力。

RAM速度の問題により、チップ設計者はCPUチップにバッファを配置する必要がありました。バッファには、CPUコアからすばやくアクセスできるコードとデータが格納されます。 RAMより遅い速度。このバッファはCPUキャッシュと呼ばれ、ほとんどのCPUには少なくとも2つあります。1次キャッシュは小さく高速で、2次キャッシュは大きく低速です。 CPUは1次キャッシュからデータと命令を読み取ることができるため、高速で実行されます。キャッシュミスは非常に高価であり、1次キャッシュにデータがない場合、CPUを最大10サイクル間スリープ状態にします。 2次キャッシュになく、RAMから読み取る必要がある場合は200サイクル。

すべてのCPUコアには独自のキャッシュがあり、RAMの独自の「ビュー」を保存します。 CPUがデータを書き込むと、キャッシュへの書き込みが行われ、キャッシュはゆっくりとRAMにフラッシュされます。必然的に、各コアはRAMコンテンツの異なるビューを持ちます。つまり、あるCPUは、そのRAM =書き込みサイクルが完了およびCPUは独自のビューを更新します。

これは、スレッド化と劇的に互換性がありません。常にreally別のスレッドによって書き込まれたデータを読み取る必要がある場合、別のスレッドの状態がどうであるかを気にします。これを保証するには、いわゆるメモリバリアを明示的にプログラムする必要があります。これは、すべてのCPUキャッシュが一貫した状態にあり、RAMの最新のビューを持つことを保証する低レベルのCPUプリミティブです。保留中の書き込みはすべてRAMにフラッシュする必要があります。その後、キャッシュを更新する必要があります。

これは.NETで利用可能で、Thread.MemoryBarrier()メソッドが実装しています。これは、ロックステートメントが実行するジョブの90%(および実行時間の95 +%)であるため、.NETが提供するツールを回避し、独自の実装を試みることで、先を行くことはできません。

19
Hans Passant

無料のデータ構造のロック および ソフトウェアトランザクションメモリ のGoogle。

これについてはジョン・スキートに同意します。ロックフリースレッドは悪魔の遊び場であり、知っておくべきことを知っていることを知っている人に任せるのが最善です。

6
Marcelo Cantos

マルチスレッドに関しては、自分が何をしているかを正確に知る必要があります。つまり、マルチスレッド環境で作業しているときに発生する可能性のあるすべてのシナリオ/ケースを調査するということです。ロックフリーマルチスレッドは、私たちが組み込むライブラリやクラスではなく、スレッドの旅で得た知識/経験です。

0
bragboy

.NETではロックフリーのスレッド化は難しいかもしれませんが、多くの場合、ロックする必要があるものを正確に調査し、ロックされたセクションを最小化することにより、ロックを使用するときに大幅な改善を行うことができます...これはロックの最小化としても知られています粒度

例として、コレクションをスレッドセーフにする必要があるとだけ言ってください。各アイテムでCPUを集中的に使用するタスクを実行する場合、コレクションを反復処理するメソッドに盲目的にロックをスローしないでください。あなたはmightのみコレクションの浅いコピーを作成するためにロックをかける必要があります。コピーを反復処理すると、ロックなしで機能します。もちろん、これはコードの詳細に大きく依存しますが、このアプローチで lock convoy の問題を修正することができました。

0
dodgy_coder