【发布时间】:2018-10-11 17:03:13
【问题描述】:
我实现了 SpinLock 类,如下
struct Node {
int number;
std::atomic_bool latch;
void add() {
lock();
number++;
unlock();
}
void lock() {
bool unlatched = false;
while(!latch.compare_exchange_weak(unlatched, true, std::memory_order_acquire));
}
void unlock() {
latch.store(false , std::memory_order_release);
}
};
我实现了上面的类并创建了两个线程,每个线程调用同一 Node 类实例的 add() 方法 1000 万次。
不幸的是,结果不是 2000 万。 我在这里想念什么?
【问题讨论】:
-
请注意,这是您可能实现的最糟糕的自旋锁。除其他问题外: 1) 当您最终获得
lock时,您将所有错误预测分支的母亲带离while循环,这是最糟糕的时间。 2)lock函数可以饿死在超线程 CPU 上同一虚拟内核中运行的另一个线程。 -
@DavidSchwartz,感谢您的 cmets。关于你提到的问题,我可以再问一下吗? 2)。该锁定功能可以使另一个线程饿死,(没错!,它的意思是这样做,因为我确信锁定的生命时间很短)。我可以使用一些旋转计数器来解决这个问题,对吗? 1)。为什么我在这段代码中使用“所有错误预测的brabches之母”?我该如何改进它?你上面有cmets吗?再次感谢您
-
暂停可防止推测执行,消除分支预测错误的惩罚。 (而且,顺便说一句,如果你对这类东西一无所知,你就没有写自旋锁的生意。你会犯每一个错误,甚至没有意识到你还有其他选择。)
-
@DavidSchwartz,我对写这类东西很感兴趣,但我对这类东西一无所知。你能推荐一个人如何让自己彻底了解这一点吗?
-
@DavidSchwartz,听起来只有尝试编写这种代码才能获得足够的知识以允许尝试编写这种代码。
标签: c++ multithreading c++11