use*_*168 2 c++ multithreading atomic
我使用InterlockedExchange编写了一个基本的自旋锁(见下文).但是我已经看到很多实现使用InterlockedCompareExchange.以某种不可预见的方式是不正确的,如果不是,每种方式的专业和缺点是什么(如果确实有的话)?
PS我知道睡眠是昂贵的,我想在我打电话之前尝试计数.
class SpinLock
{
public:
SpinLock() : m_lock( 0 ) {}
~SpinLock(){}
void Lock()
{
while( InterlockedExchange( &m_lock, 1 ) == 1 )
{
Sleep( 0 );
}
}
void Unlock()
{
InterlockedExchange( &m_lock, 0 );
}
private:
volatile unsigned int m_lock;
};
Run Code Online (Sandbox Code Playgroud)
首先,InterlockedExchange
需要一个LONG
.请在我之后重复:a LONG
是不一样的int
.这似乎是一件小事,但它可能会让你感到悲伤.
现在,详细说明Mats Petersson所说的内容:
您的自旋锁将具有可怕的性能,因为InterlockedExchange循环Lock
将m_lock
无条件地修改变量,导致后台处理器完成大量工作以维持缓存一致性.
更糟糕的是,通过不确保m_lock
变量本身位于缓存行上,上述效果被放大并可能影响其他数据,不幸的是,它们与自旋锁的实例共享缓存行.
这些代码只是两个中度微妙的问题.还有其他人.简单的事实是锁定不容易,你不应该实现自定义锁定原语.请不要重新发明轮子.使用操作系统提供给您的工具.它们本身不太可能成为瓶颈.
如果您确实发现性能问题(即,您具有表明性能瓶颈的分析数据),请首先关注算法更改以及改进并行化和减少锁争用.如果问题仍然存在,那么只有在其他地方看.
归档时间: |
|
查看次数: |
2424 次 |
最近记录: |