簡體   English   中英

InterlockedExchange vs InterlockedCompareExchange自旋鎖

[英]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 請在我之后重復: LONGint 這似乎是一件小事,但它可能會讓你感到悲傷。

現在,詳細說明Mats Petersson所說的話:

由於Lock的InterlockedExchange循環將無條件地修改m_lock變量,因此你的自旋鎖將具有可怕的性能,導致后台處理器完成大量工作以維持緩存一致性。

更糟糕的是,通過不確保m_lock變量本身位於緩存行上,上述效果被放大並可能影響其他數據,不幸的是,它們與自旋鎖的實例共享緩存行。

這些代碼只是兩個中度微妙的問題。 還有其他人。 簡單的事實是鎖定不容易,你不應該實現自定義鎖定原語。 請不要重新發明輪子。 使用操作系統提供給您的工具。 它們本身不太可能成為瓶頸。

如果您確實發現性能問題(即,您具有表明性能瓶頸的分析數據),請首先關注算法更改以及改進並行化和減少鎖爭用。 如果問題仍然存在, 那么只有在其他地方看。

CMPXCHG和XCHG之間幾乎沒有區別(這是你從你提到的兩個內部函數中得到的x86指令)。

我認為主要區別在於,在一個對鎖具有很多爭用的SMP系統中,當值已經“鎖定”時,你不會得到一堆寫入 - 這意味着其他處理器不必讀取返回緩存中已存在的值。

在調試版本中,您還需要確保僅從鎖的當前所有者調用Unlock()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM