我编写了一个简单的程序来测试CLH锁的吞吐量。 我的代码就像“多核编程艺术”一书中所描述的那样。接下来,我在一个不断变化的线程数上运行一个计数器10秒钟,并将counter / 10.0定义为吞吐量。
我的问题是我得到的结果是否在逻辑范围内,以及它们的原因可能是什么。我问,因为CLH锁的吞吐量下降非常快。 这些是cLH锁定的结果,其中左边指定线程计数,右边是吞吐量(计数器得到的大小,每个线程在CLH锁保护的临界区域中递增一次,除以10)。 / p>
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秒,而其他线程尝试锁定,递增,然后解锁,直到挥发性布尔告诉他们时间已到。
答案 0 :(得分:1)
关于您的CLH锁定实施
除繁忙旋转外,实现看起来相当标准。你可能最好放弃或停车(虽然这需要更多的代码)。
关于您的基准测试结果
从性能测试中判断某些代码的正确性是一项任务,至少需要从正确性测试中判断某些代码的正确性所需的知识。
您可能正在观察与您的代码无直接关系的众多副作用。为了最大限度地减少这些影响,请使用像JMH这样的基准测试工具,否则您正在测量的东西不一定是您的代码。
这是关于您的结果的推测性解释,可能不正确,但完全合情合理: