![](/img/trans.png)
[英]InterlockedExchange vs. InterlockedExchangePointer
[英]InterlockedExchange vs InterlockedCompareExchange spin locks
我使用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;
};
首先, InterlockedExchange
需要很LONG
。 請在我之后重復: LONG
與int
。 這似乎是一件小事,但它可能會讓你感到悲傷。
現在,詳細說明Mats Petersson所說的話:
由於Lock
的InterlockedExchange循環將無條件地修改m_lock
變量,因此你的自旋鎖將具有可怕的性能,導致后台處理器完成大量工作以維持緩存一致性。
更糟糕的是,通過不確保m_lock
變量本身位於緩存行上,上述效果被放大並可能影響其他數據,不幸的是,它們與自旋鎖的實例共享緩存行。
這些代碼只是兩個中度微妙的問題。 還有其他人。 簡單的事實是鎖定不容易,你不應該實現自定義鎖定原語。 請不要重新發明輪子。 使用操作系統提供給您的工具。 它們本身不太可能成為瓶頸。
如果您確實發現性能問題(即,您具有表明性能瓶頸的分析數據),請首先關注算法更改以及改進並行化和減少鎖爭用。 如果問題仍然存在, 那么只有在其他地方看。
CMPXCHG和XCHG之間幾乎沒有區別(這是你從你提到的兩個內部函數中得到的x86指令)。
我認為主要區別在於,在一個對鎖具有很多爭用的SMP系統中,當值已經“鎖定”時,你不會得到一堆寫入 - 這意味着其他處理器不必讀取返回緩存中已存在的值。
在調試版本中,您還需要確保僅從鎖的當前所有者調用Unlock()
!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.