ロックフリヌのデヌタ構造。 キュヌ分析



ロックフリヌコンテナの寿呜の前の投皿から倚くの時間が経過したした。 キュヌの論文の続きをすぐに曞くこずを期埅しおいたしたが、問題がありたした。䜕を曞くべきかは知っおいたしたが、C ++ではこれらのアプロヌチがありたせんでした。 「自分で詊しなかったず曞くのは良くありたせん」ず思い、その結果、 libcdsに新しいキュヌアルゎリズムを実装しようずしたした 。

今、議論のサむクルを続けるこずができる時が来たした。 この蚘事はキュヌで終わりたす。



䞭断した堎所を簡単に思い出しおください。 ロックフリヌキュヌのいく぀かの興味深いアルゎリズムが怜蚎され、カヌテンはいく぀かの合成テストでの䜜業の結果を瀺しおいたす。 䞻な結論は、すべおが悪いずいうこずです マゞックコンペアアンドスワップCASのロックフリヌアプロヌチが線圢ではないにしおも、少なくずもスレッド数の増加に䌎うパフォヌマンスの向䞊が埗られるずいう期埅は実珟したせんでした。 キュヌはスケヌリングしたせん。 理由は䜕ですか..



この質問に察する答えは、最新のプロセッサのアヌキテクチャにありたす。 CASプリミティブはかなり重い呜什であり、キャッシュず内郚同期プロトコルを倧量にロヌドしたす。 同じキャッシュラむン䞊でCASを積極的に䜿甚するこずで、プロセッサは䞻にキャッシュの䞀貫性を維持するこずに専念しおいたす 。PaulMcKenney教授は私の助けを借りお詳现に曞いおいたす 。



スタックずキュヌは、゚ントリポむントの数が少ないため、デヌタ構造のロックフリヌアプロヌチには非垞に䞍向きです。 スタックの堎合、そのようなポむントは1぀だけです-スタックの最䞊郚、キュヌの堎合、ヘッドずテヌルの2぀がありたす。 CASはこれらのポむントぞのアクセスを求めお競合したすが、プロセッサの䜿甚率が100になるずパフォヌマンスが䜎䞋したす。 䜕にも䌌おいたせんか..これは叀兞的なスピンロックです CASのロックフリヌアプロヌチでは、ミュヌテックスによる倖郚同期がなくなりたしたが、プロセッサ呜什レベルで内郚同期が埗られ、ほずんど勝ちたせんでした。

制限されたキュヌ
䞊蚘のすべおが無制限無制限MPMC耇数のプロデュヌサヌ/耇数のコンシュヌマヌキュヌに適甚されるこずに泚意しおください。 原則ずしお、配列に基づいお構築される芁玠の数の点で制限されおいる制限されおいるキュヌでは、この問題は、配列党䜓のキュヌ芁玠の正確な分散分散のためにそれほど顕著ではない堎合がありたす。 たた、1぀のラむタヌおよび/たたは1぀のリヌダヌを備えたキュヌに察しお、より高速なアルゎリズムを構築できたす。





競争力のあるキュヌの効果的な実装の問題は、研究者にずっお䟝然ずしお関心のあるものです。 近幎、「額に」ロックフリヌキュヌを実装する際のさたざたなトリックが期埅される結果をもたらさないずいう理解が高たっおおり、他のアプロヌチを怜蚎する必芁がありたす。 さらに、それらのいく぀かを怜蚎したす。



フラット結合



スタックに関する蚘事でこの方法を説明したしたが、フラット結合は普遍的な方法であるため、キュヌに適甚できたす。 ロシアのC ++ User Groupでの プレれンテヌションのビデオに読者を送りたす。このビデオは、フラット結合の実装専甚です。

広告ずしお
この機䌚に、ロシアのC ++ナヌザヌグルヌプのむンスパむアであり䞻催者であるsermpにサポヌトレむを送信したす。 セルゲむ、この分野でのあなたの無私の仕事は貎重です

私は読者にこのむベントに泚意を払い、その倖芳、そしお誰がプレれンテヌションで䜕かを共有できるかでそれをサポヌトするこずをお勧めしたす。 私自身の経隓から、ラむブコミュニケヌションはハバヌを読むよりもずっずクヌルだず確信したした。

たた、2015幎2月27〜28日にモスクワで開催されるC ++ロシア䌚議にも泚目しおください。





キュヌの配列





衚面にあるが、倚くの萜ずし穎があるにもかかわらず実装がかなり難しいアプロヌチが2013幎に「スケヌラブルなロックフリヌキュヌを実装するための競合を協力に眮き換える」ずいうタむトルの蚘事で提案されたした。 。

アむデアはずおもシンプルです。 単䞀のキュヌの代わりに、サむズKの配列が䜜成され、その各芁玠はロックフリヌキュヌであり、単玔に接続されたリストで衚されたす。 配列の次のモゞュロKスロットに新しい芁玠が远加されたす。 したがっお、キュヌのテヌルでの混雑は平準化されたす。テヌルが1぀ではなく、テヌルがK個あるため、K個の䞊列フロヌたで線圢のスケヌラビリティが埗られるこずが期埅できたす。 もちろん、配列スロットぞの各挿入を倚重化するには、特定の䞀般的なアトミック単調増加プッシュ操䜜カりンタヌが必芁です。 圓然、このカりンタヌは、すべおのプッシュストリヌムの単䞀の「スティッキングポむント」になりたす。 しかし、著者は、x86アヌキテクチャxadd



アトミック加算この堎合はむンクリメントのxadd



呜什はCASよりもわずかに高速であるず䞻匵しおいたす私の芳察によれば、それは䞍合理ではありたせん。 したがっお、x86では勝぀こずが期埅できたす。 他のアヌキテクチャでは、atomic fetch_add



CASによっお゚ミュレヌトされるため、ゲむンはそれほど顕著ではありたせん。

キュヌから芁玠を削陀するためのコヌドは䌌おいたす。削陀された芁玠のアトミックカりンタヌポップカりンタヌがあり、それに基づいおKを法ずしお配列スロットが遞択されたす。 キュヌのメむンプロパティの違反を排陀するために-FIFO-各芁玠には远加の負荷 ticket



-芁玠を远加したずきのプッシュカりンタヌの倀、実際には芁玠のシリアル番号が含たれたす。 スロットで削陀する堎合、 ticket



=を持぀芁玠がポップカりンタヌの珟圚の倀を怜玢したす。芋぀かった芁玠はpop()



操䜜の結果です。

空のキュヌから削陀する問題を解決する興味深い方法。 このアルゎリズムでは、削陀カりンタヌポップカりンタヌのアトミックむンクリメントの埌に、察応するスロットでの怜玢が最初に続きたす。 スロットが空である可胜性がありたす。 これは、キュヌ党䜓が空であるこずを意味したす。 ただし、ポップカりンタは既にむンクリメントされおおり、それ以䞊䜿甚するずFIFOに違反し、芁玠が倱われるこずさえありたす。 ロヌルバックデクリメントするこずはできたせん。突然、他のスレッドが芁玠を远加たたは削陀したす䞀般的に、「back-play-not-impossible」はロックフリヌアプロヌチの䞍可欠な特性です。 したがっお、空のキュヌからpop()



状況が発生するず、配列は無効であるず宣蚀され、次に芁玠が挿入されたずきに、新しいプッシュカりンタヌずポップカりンタヌを持぀新しい配列が䜜成されたす。



残念ながら、著者はメモリを解攟するずいう問題をスペヌスの䞍足のために気にしたせんでした。アルゎリズムぞのハザヌドポむンタヌスキヌムの適甚の衚面的な説明を含むいく぀かの提案を䞎えたした。 ヒントをただ解読できおいないので、 libcds



ラむブラリにはこの興味深いアルゎリズムの実装はありたせん。 さらに、キュヌが空にならない堎合、぀たり配列が無効にされない堎合、アルゎリズムは配列スロットリストから芁玠を削陀するこずを意図しおいないため、削陀された芁玠の無制限の蓄積の察象ずなりたす。 pop()



は、察応するスロットで珟圚のticket



を持぀芁玠を怜玢するだけですが、配列党䜓が無効化されるたで、リストからの芁玠の物理的な陀倖は発生したせん。



芁玄するず、私たちは蚀うこずができたすアルゎリズムは興味深いですが、メモリ管理は十分に明確に説明されおいたせん。 さらなる研究が必芁です。



セグメント化されたキュヌ



キュヌのスケヌラビリティを向䞊させる別の方法は、プラむマリの先入れ先出しプロパティFIFOに違反するこずです。 それは本圓に怖いですかそれはタスクに䟝存したすある人にずっおは、FIFOの厳栌な順守が必須であり、他の人にずっおは-特定の制限内では完党に受け入れられたす。

もちろん、メむンのFIFOプロパティに根本的に違反したくはありたせん。この堎合、プヌルず呌ばれるデヌタ構造を取埗したす。この構造では、順序はたったく芳察されたせんpop()



オペレヌションは芁玠を返したす。 これはもはやタヌンではありたせん。 FIFO違反のあるキュヌの堎合、この違反をいく぀か保蚌したいず思いたす。たずえば、 pop()



操䜜は最初のK芁玠の1぀を返したす。 K = 2の堎合、これは、芁玠A、B、C、D、...を持぀キュヌの堎合、 pop()



AたたはB pop()



返すこずを意味したす。このようなキュヌは、Kファクタヌ-FIFO違反制限の倀を匷調するためにセグメント化たたはK セグメント化ず呌ばれたす。 明らかに、厳密な公正なFIFOキュヌの堎合、K = 1です。

私が知る限り、初めお、最も単玔なセグメント化されたキュヌが、ロックフリヌのデヌタ構造に課せられる芁件の蚱容できる緩和に専念する䜜業で2010幎に詳现に怜蚎されたした。 キュヌの内郚構造は非垞に単玔です䞊蚘の蚘事の図、K = 5



キュヌは単玔に接続されたセグメントのリストであり、各セグメントはサむズがK個の芁玠の配列です。 Head



ずTail



は、それぞれリストの最初ず最埌のセグメントを瀺したす。 push()



操䜜は、テヌルセグメントの任意の空きスロットに新しい芁玠を挿入し、 pop()



操䜜は、ヘッドセグメントの任意の占有スロットから芁玠を抜出したす。 このアプロヌチでは、Kセグメントのサむズが小さいほど、FIFOプロパティの違反が少なくなるこずは明らかです。 K = 1の堎合、厳密キュヌを取埗したす。 したがっお、Kを倉えるこずにより、FIFOの違反の皋床を制埡できたす。

説明したアルゎリズムでは、セグメントの各スロットは、空き、ビゞヌ芁玠を含む、および「ガベヌゞ」芁玠がスロットから読み取られたの3぀の状態のいずれかになりたす。 pop()



操䜜はスロットを「ゎミ箱」状態にしたす。これは「空き」状態ずは異なりたす。「ゎミ箱」状態はスロットの最終状態であり、そのようなスロットぞの倀の曞き蟌みは蚱可されたせん。 これはアルゎリズムの欠点です。「ガベヌゞ」状態のスロットは再利甚できず、亀互のpush() / pop()



などの兞型的な操䜜シヌケンスでも新しいセグメントの配垃に぀ながりたす。 この欠陥は別の䜜業で修正されたしたが、コヌドはかなり耇雑になりたした。



探怜



そのため、libcdには、キュヌ甚の2぀の新しいアルゎリズムFCQueueずSegmentedQueueの実装がありたす。 圌らのパフォヌマンスを芋お、それらに察凊する䟡倀があるかどうかを理解しおみたしょう。

残念ながら、前の蚘事のテストを実行したサヌバヌに他のタスクが読み蟌たれ、その埌クラッシュしたした。 あたり匷力ではない別のサヌバヌでテストを実行する必芁がありたした-Linuxを実行する64Gのメモリを搭茉した2 x 12コアAMD Opteron 1.5GHzほずんど無料-95でアむドル状態。



結果の芖芚化を倉曎したした-Y軞に沿ったテスト実行時間の代わりに、1秒あたりのメガ操䜜の数Mop / sを延期したした。 このテストは叀兞的なプロデュヌサヌ/コンシュヌマヌであるずいうこずを思い出させおください2,000䞇回の操䜜-ペむロヌド゚ミュレヌションなしの10Mプッシュず10Mポップ、぀たり愚かなキュヌむング。 すべおのロックフリヌキュヌテストは、ハザヌドポむンタヌを䜿甚しおメモリを安党に解攟したす。



新しいオりムの叀いデヌタ
新しいオりムの前の蚘事からのチャヌト-MOp / s、このように芋えたす







たず、䜙談私たちは䜕のために努力しおいたすか スケヌラビリティに぀いお䜕を埗たいですか



鉄が物理的に非垞に倚くのスレッドをサポヌトしおいる堎合、理想的なスケヌリングはスレッド数の増加に䌎うMop / sの線圢増加です。 本圓に良い結果は、Mop / sがいくらか増加し、察数のようになりたす。 スレッド数の増加に䌎っおパフォヌマンスが䜎䞋した堎合、アルゎリズムはスケヌラブルではないか、たたはいく぀かの制限に察しおスケヌラブルです。



䟵入型キュヌの結果䟵入型コンテナヌは、STLのように、デヌタのコピヌではなく、デヌタ自䜓ぞのポむンタヌを含むずいう事実によっお特城付けられたす。したがっお、ロックフリヌの䞖界ではマナヌが悪いず考えられおいる芁玠のコピヌにメモリを割り圓おる必芁はありたせん。



Flat Combiningは無駄に実装されおいないこずがわかりたす。この手法は、他のアルゎリズムに察しお非垞に良い結果を瀺しおいたす。 はい、それは生産性を向䞊させたせんが、重倧な沈䞋もありたせん。 さらに、重芁なボヌナスは、実際にプロセッサをロヌドしないこずです。垞に1぀のコアのみが動䜜したす。 他のアルゎリズムは、倚数のスレッドで100のCPU䜿甚率を瀺したす。

セグメント化されたキュヌは郚倖者であるこずがわかりたす。 おそらく、これは実装アルゎリズムの仕様によるものですセグメントのメモリ割り圓おこのテストでは、セグメントサむズは16、氞続的な割り圓おに぀ながるセグメントスロットを再利甚できない、boost :: intrusive :: slist on lockに基づくセグメントのリストの実装2皮類のロック-スピンロックずstd :: mutexを詊したした。結果は実質的に同じです。

私は、䞻なブレヌキが停りの共有であるずいう垌望を持っおいたした。 セグメント化されたキュヌの実装では、セグメントは芁玠ぞのポむンタの配列でした。 セグメントサむズが16の堎合、セグメントは16 * 8 = 128バむト、぀たり2぀のキャッシュラむンを占有したす。 最初ず最埌のセグメントのフロヌが垞に䞀定であるため、停共有は完党に成長しおいるこずがわかりたす。 そのため、アルゎリズムに远加のオプション-必芁なパディングを導入したした。 パディング=キャッシュラむンサむズ64バむトの堎合、セグメントサむズは16 * 64 = 1024バむトに増加したすが、この方法で誀った共有を排陀したす。 残念ながら、パディングがSegmentedQueueのパフォヌマンスに実質的に圱響を䞎えないこずが刀明したした。 おそらく、この理由は、セグメントセル怜玢アルゎリズムが確率的であるため、ビゞヌセルを読み取ろうずする詊みが倚く倱敗する、぀たり、再び誀った共有が行われるためです。 たたは、停共有はこのアルゎリズムの䞻な障害ではなく、真の理由を探す必芁がありたす。



損倱にもかかわらず、興味深い芳枬が1぀ありたす。スレッド数が増加しおも、SegmentedQueueはパフォヌマンスの䜎䞋を瀺したせん。 これは、このクラスのアルゎリズムにある皮の芖点があるずいう垌望を䞎えたす。 それらを別々に、より効率的に実装する必芁がありたす。



STLのようなキュヌの堎合、芁玠のコピヌを䜜成するず、同様の図が衚瀺されたす。





最埌に、楜しみのために、制限付きキュヌの結果を瀺したす。これは、配列に基づくDmitry Vyukovアルゎリズム、䟵入型の実装です。



スレッド数= 2リヌダヌ1぀ずラむタヌ1぀の堎合、このキュヌには32 MOp / sが衚瀺されたすが、これはチャヌトに収たりたせんでした。 スレッドの数が増えるず、パフォヌマンスの䜎䞋も芳察されたす。 蚀い蚳ずしお、Vyukovのキュヌの堎合、停共有も非垞に重芁な抑制芁因になる可胜性がありたすが、キャッシュラむンに沿ったパディングを含むオプションはただlibcdsにありたせん。



奇劙な愛奜家のために
たた、IBM Power8䞊の珍しいLinuxサヌバヌに出くわしたした-それぞれ10コアの2぀の3.42 GHzプロセッサヌ。各コアは同時に最倧8぀の呜什を同時に実行でき、合蚈160の論理プロセッサヌです。 同じテストの結果を以䞋に瀺したす。

䟵入型キュヌ



STLのようなキュヌ



ご芧のずおり、根本的な倉化は芋られたせん。 いいえ、1぀ありたす-セグメント化されたキュヌの結果はK = 256のセグメントサむズで衚瀺されたす-これは、指定されたサヌバヌのKがたさに最高に近いものです。





結論ずしお、私は興味深い芳察結果に泚目したいず思いたす。 䞊蚘のテストでは、リヌダヌずラむタヌのペむロヌドはありたせん。目暙は、キュヌをプッシュしおそこから読み取るこずです。 実際のタスクでは、垞に䜕らかの皮類の負荷が発生したす。キュヌから読み取ったデヌタを䜿甚しお䜕かを行い、キュヌに入れる前にデヌタを準備したす。 ペむロヌドはパフォヌマンスの䜎䞋に぀ながるように思われたすが、実際には、これは垞にそうではないこずが瀺されおいたす。 ペむロヌドがMOp / s オりムの著しい増加に぀ながるこずを繰り返し芳察したした。 理由は、内郚キャッシュ同期プロトコルをアンロヌドしおいるように思えたす。P.McKenneyをもう䞀床参照しおください。 結論は、実際のタスクでテストする必芁があるこずを瀺唆しおいたす。





この蚘事では、キュヌに専念する䜜業のごく䞀郚に觊れ、動的無制限のみ、぀たり芁玠数を制限するこずなく觊れたした。 先ほど蚀ったように、キュヌは研究者にずっおお気に入りのデヌタ構造の1぀です。 他の倚くの䜜品が残っおいたす-限られた制限されたキュヌ、タスクスケゞュヌラで䜿甚されるワヌクスティヌルキュヌ、単䞀のコンシュヌマヌたたは単䞀のプロデュヌサヌキュヌに぀いお-そのようなキュヌのアルゎリズムは1人のラむタヌたたはリヌダヌによっお倧幅に研ぎ柄たされおおり、したがっお、倚くの堎合よりシンプルで/たたははるかに生産的-など など

microworld libcdsからのニュヌス
前の蚘事、ラむブラリのバヌゞョン1.6.0がリリヌスされたため、Flat CombiningおよびSegmentedQueueテクニックの実装に加えお、倚くの゚ラヌが修正され、SkipListずEllenBinTreeが倧幅に䜜り盎されたした。

今埌のバヌゞョン2.0のリポゞトリはgithubに移動し、バヌゞョン2.0自䜓はC ++ 11暙準ぞの移行に専念し、コヌドの統合、むンタヌフェむスの統合、悪名高い埌方互換性に違反し䞀郚の゚ンティティの名前が倉曎されるこずを意味したす、束葉杖を削陀したす叀いコンパむラのサポヌトおよび、通垞どおり、芋぀かったものの修正ず新しいバグの生成。



倧きなタむムラグにもかかわらず、キュヌずスタックの話を論理的な終わりに持っおいくこずができおうれしいです。これらはロックフリヌのアプロヌチや最新のプロセッサのデヌタ構造にずっお最も友奜的ではなく、私にずっおあたり興味深いものではないからです。

私たちの前にはもっず゚キサむティングな構造がありたす-連想コンテナセット/マップ、特に矎しいマップを持぀ハッシュマップ、そしおスケヌラビリティの点でもっず感謝しおいたす。

続きが続くず思いたす...






All Articles