基本上,我的问题是:
自旋锁的“好”实现在c ++中是什么样的,它适用于“通常”的CPU / OS /编译器组合(x86& arm,Windows& Linux,msvc& clang& g ++(也许)也icc))。
解释
正如我在different question的答案中写的那样,在c ++ 11中编写一个有效的自旋锁是相当容易的。然而,正如所指出的那样(在评论中以及例如spinlock-vs-stdmutextry-lock中),这样的实现在拥塞时会出现一些性能问题,这只能通过使用特定于平台的指令来解决(内在函数/ os原语) / 部件?)。
我不是在寻找一个超级优化的版本(我希望只有你对确切的平台和工作量有非常精确的知识并且需要最后一点效率才有意义)但是生活在神话中的东西20 / 80权衡点即我想在大多数情况下避免最重要的陷阱,同时仍然尽可能简化和理解解决方案。
一般来说,我希望结果看起来像这样:
#include <atomic>
#ifdef _MSC_VER
#include <Windows.h>
#define YIELD_CPU YieldProcessor();
#elif defined(...)
#define YIELD_CPU ...
...
#endif
class SpinLock {
std::atomic_flag locked = ATOMIC_FLAG_INIT;
public:
void lock() {
while (locked.test_and_set(std::memory_order_acquire)) {
YIELD_CPU;
}
}
void unlock() {
locked.clear(std::memory_order_release);
}
};
但我不知道
如果循环中的YIELD_CPU宏是所有需要的,或者是否存在任何其他有问题的方面(例如,我们是否应该指示我们是否希望test_and_set在大多数时间内成功)
YIELD_CPU
在不同CPU / OS /编译器组合上的适当映射是什么(如果可能的话,我想避免拖动像Windows.h
这样的重量级标题< / p>
注意:我也对仅涵盖所提及平台的一部分的答案感兴趣,但可能不会将它们标记为已接受的答案和/或将它们合并到单独的社区答案中。