C#タグでこの質問をしますが、可能であればどの言語でも可能です。ロック(待機)フリーの二重リンクリストは可能ですか?
ノーウェイトロックを提供するために連動操作を使用して二重リンクリストを実装することは可能ですか?私は挿入し、追加し、削除し、待たずにクリアしたいと思う。
C#タグでこの質問をしますが、可能であればどの言語でも可能です。ロック(待機)フリーの二重リンクリストは可能ですか?
ノーウェイトロックを提供するために連動操作を使用して二重リンクリストを実装することは可能ですか?私は挿入し、追加し、削除し、待たずにクリアしたいと思う。
単純なgoogle検索では、多くのロックフリーの二重リンクリストペーパーが公開されます。
ただし、それらは原子CAS(比較とスワップ)に基づいています。
私はC#での操作がどのように原子知りませんが、このウェブサイトによると
http://www.albahari.com/threading/part4.aspx
C#の操作はのみ読み取りおよび32ビットのフィールドを記述するための原子であることが保証されています。 CASの言及はありません。
ワンショットで複数のリファレンスを設定する必要があり、連動した操作の能力が限られているので、これは可能ではないと思います。
たとえば、AとCの間にノードBを挿入する場合は、B-> next、B-> prev、A-> next、およびC-> prevを1つに設定する必要があります原子操作。連動してもそれは処理できません。 Bの要素をプリセットすることは助けにはならない。なぜなら、「B」を準備している間に別のスレッドが挿入を行うことができるからだ。
私はこの場合ロックを可能な限り細かくし、それを排除しようとはしません。
"可能な限り細かいロックを取得する" - アプリケーションのマクロ動作に応じて、多くの短いロックを取り出すコストが避けられた待機時間よりも重要な場合があるため、速度が遅くなる可能性があります。 –
良い点、Earwicker。プロファイリングにはここで利点があります –
この回答は間違っています。二重リンクリストが実装されました。キーは、バックポインタが常に最新のものではないため、逆方向にトラバースするときには余分な作業が必要です。 –
私は答えが非常に深い認定されていると言います。「はい、それはです。ですが、難しいです。あなたが求めているものを実装するには、基本的には、衝突を起こさないために操作をまとめてコンパイルするものが必要です。したがって、その目的のために一般的な実装を作成することは非常に難しく、依然としていくつかの重要な制限があります。正確なニーズに合わせた特定の実装を作成する方が簡単かもしれませんし、それでいてどんな方法でも「シンプル」ではないでしょう。
「衝突を確実に防ぐために操作をまとめてコンパイルするもの」 - それはどういう意味ですか? –
現代のCPUが高い命令スループットを達成するために1つのコアで複数の実行ユニットをどのように利用するか、命令の実行ユニットとの相互作用が非相互依存性であることがチェックされ、マイクロ命令がインターリーブされ、順序依存の動作がすべて保持される。これは基本的にコンパイル操作です。 –
ほとんどの言語では、コンパイラとCPUの両方から読取り/書込み操作を移動できないようにする何らかの「メモリ障壁」が備わっているため、これはほとんど問題ではないため、操作を再配置しないことを確認できますあなたがコードであることを無効にする方法で。 (その理由は、c/C++のvolatileキーワードが発明されたのですが、volatileは他の揮発性変数に対してのみ保証されているため、メモリバリアが導入されています)。 –
paperここには、ロックフリーの二重リンクリストがディスクリートされています。
我々は 互いに素並列アクセス可能であり、現代のコンピュータシステムに 用意されてい アトミックプリミティブを使用しています 同時両端キューの効率的かつ実用的な ロックフリーな実装を提示。以前にdequeの の公知のロックフリーアルゴリズムはいずれかの非利用可能 原子同期プリミティブに基づいている、 のみ機能のサブセットを実装する、または 互いに素なアクセスのために設計されていません。当社のアルゴリズムは、二重リンクリストに基づいて で、 は、単一の単語 スワップを比較-と-を必要と...
ロスBencinaは、私はちょうどnumerious論文やソースコードexcamplesで見つかったいくつかの本当に良いリンクがあります"Some notes on lock-free and wait-free algorithms"の場合
しかし、AFAIK、* ALL *の二重リンクリスト(実際には、単独でリンクされたリストでもよい)はGCを必要とします。 –
私はValoisの1995年の単独リンクリストはGCを必要としないと信じています - 私はこの論文を読む必要があります。 –
Valois紙では、参照カウントを使用してロックフリーのメモリ管理を保証しています。参照カウントは、ノードへのグローバルポインタの数を表す。さらに、各スレッドは、現在使用しているノードへのポインタのハザードリストを保持します。スレッドが参照カウント0のハザードリストからポインタを削除したい場合、他のスレッドのハザードリストをスキャンして、誰かがまだそれを使用しているかどうかを確認し、誰も削除しないようにする必要があります。ロックを取ることなくハザードリストを安全にスキャンするには、いくつかのトリックがあります。 – JanKanis
FWIWでは、.NET 4.0では、システムにスレッドセーフな二重リンクリストであるConcurrentLinkedListが追加されています。Collections.Concurrent名前空間。あなたはdocumentationまたはそれを記述するblog postを読むことができます。
スレッドセーフでは決してロックフリーではありません。 –
脚注を読む - 彼らは4.0から前にVS2010
の最終リリースさて、あなたが実際にそれを行う方法を求めていないにConcurrentLinkedListを引っ張っていく予定です。しかし、C#で原子CASを行うことができれば、それは完全に可能です。
実際、私はちょうどC++の二重にリンクされた待機フリーリストの実装を行っています。
ここにそれを記述する論文があります。 http://www.cse.chalmers.se/~tsigas/papers/Haakan-Thesis.pdf
またプレゼンテーションでは、いくつかの手がかりを得ることができます。
はい、可能ですが、私のSTLのような実装は、Lock-Free Doubly-Linked ListのC++です。
Sample code that spawns threads to randomly perform ops on a list
これはABAの問題なく動作する64ビットのコンペアアンドスワップを必要とします。このリストはlock-free memory managerのためにのみ可能です。
benchmarks on page 12をご覧ください。リストのパフォーマンスは、競合が増加するにつれてスレッドの数に比例して増加します。このアルゴリズムは、ディスジョイント・アクセスの並列性をサポートしているため、リスト・サイズが増加すると競合が減少する可能性があります。
すべてほとんどのアーキテクチャ[1]のロック可能なアルゴリズムを書くことができます。しかし、効率の良いものを書くのは難しいです。
私はlock-free doubly linked list by Håkan Sundell and Philippas Tsigasのimplementationを.Netに書いています。注意してください、それは概念のために原子のPopLeftをサポートしていません。
[1]:Maurice Herlihy: Impossibility and universality results for wait-freesynchronization (1988)
は、すべてのスレッドがプロセスを作ることができる無料の手段を待って、いくつかのスレッドが進歩を遂げることができます無料の手段をロック....無料のロックとフリー待つ異なっています。 – user997112