私は、CLHロックのスループットをテストするための簡単なプログラムを作成しました。 「マルチコアプログラミングの芸術」の本で説明したようなコードがあります。次に、変化するスレッド数で10秒間カウンタを実行し、スループットとしてカウンタ/ 10.0を定義しました。SpinLockのスケーラビリティと制限
私の質問は、私が得た結果が論理的な範囲内にあるかどうかと、それが彼らの方法である理由かもしれません。私はCLHロックのスループットの低下が非常に速いので尋ねます。 これはcLHロックの結果です。左はスレッド数を指定し、右はスループット(各スレッドがCLHロックで保護されたクリティカルセクションで1度インクリメントするサイズを10で割ったもの)です。
CLH 1 2.89563825E7 2 1.33501436E7 4 5675832.3 8 15868.9 16 11114.4 32 68.4
あなたはドロップオフは非常識であると私は何か他のものまでを台無しかもしれないことを考えさせる見たよう。
これは(それが上記の本であると同じように)CLHロックのために私のコードです:他の人がロックしようとしながら
static class CLHLock implements Lock {
AtomicReference<QNode> tail;
ThreadLocal<QNode> myNode, myPred;
public CLHLock() {
tail = new AtomicReference<QNode>(new QNode());
this.myNode = new ThreadLocal<QNode>() {
protected QNode initialValue() {
return new QNode();
}
};
this.myPred = new ThreadLocal<QNode>() {
protected QNode initialValue() {
return null;
}
};
}
public void lock() {
QNode qnode = this.myNode.get();
qnode.locked.set(true);
QNode pred = this.tail.getAndSet(qnode);
myPred.set(pred);
while (pred.locked.get()) {}
}
public void unlock() {
QNode qnode = this.myNode.get();
qnode.locked.set(false);
this.myNode.set(this.myPred.get());
}
static class QNode {
public AtomicBoolean locked = new AtomicBoolean(false);
}
}
ランは10秒間待機しているメインスレッドで構成され、インクリメントその後、揮発性のブール値が時間が上がったことを知らせるまでロックを解除します。あなたのCLHロックの実装について
私の経験では、ほとんどの劣化はスピンのCPUホギングに起因しています。 'while(pred.locked.get()){}'はおそらく 'while(pred.locked.get()){Thread.yield();}'ともっと社交的になります。違いはないので、コメントしてください。 – OldCurmudgeon