私は、クラビング手法を使用して B+Tree のメモリ内バージョンを開発していました (親のロックを解放する前に、子のロックを取得する必要があります)。
実装のターゲット言語は C# です。私の実装ではバッキングがDictionary<Page, Node>
あります。XS および U ラッチの場合、Dictionary で使用可能なすべてのノードに対して個別の ReaderWriterLockSlim を使用します。したがって、SLatch の取得は基本的に次のようになります。
internal void SLatch(long page)
{
nodes[page].locker.EnterReadLock();
}
マルチスレッド テストを実行すると、ツリーの動作に非常に奇妙なパターンが見られます。テストでは、16 コアのマシンと 10 000 000 ロングを使用しました。ツリー キーの数は 16 であるため、600,000 近くの DataNode オブジェクトと 70,000 の IndexNode オブジェクトがあります。
8 つのスレッドで同時にテストを実行すると、ツリーに値が挿入されます。最初は、コアの使用量が 1 コアから 3 に直線的に増加していることがわかります。しかし、開始からしばらくすると、平均で 1.5 コアに戻り、コア使用率が一定になります。並列プロファイラでは、ピーク前は 3 つのコア プロセスが互いに待機してほとんどスリープしていましたが、ピーク後には互いにブロックされるのを待機し始めました。
問題をどこで見るべきか、または私が使用するアプローチの欠陥は何か、誰かがアイデアを提案できますか?
ありがとう。