0

ブーストスピンロックコードにいくつか質問があります:

class spinlock
{
public:
    spinlock()
        : v_(0)
    {
    }

    bool try_lock()
    {
        long r = InterlockedExchange(&v_, 1);
        _ReadWriteBarrier();        // 1. what this mean            
        return r == 0;
    }

    void lock()
    {
        for (unsigned k = 0; !try_lock(); ++k)
        {
            yield(k);
        }
    }

    void unlock()
    {

        _ReadWriteBarrier();                      
        *const_cast<long volatile*>(&v_) = 0;  
        // 2. Why don't need to use InterlockedExchange(&v_, 0);
    }

private:
    long v_;
};
4

3 に答える 3

1
  1. A ReadWriteBarrier() is a "memory barrier" (in this case for both reads and writes), a special instruction to the processor to ensure that any instructions resulting in memory operations have completed (load & store operations - or in for example x86 processors, any opertion which has a memory operand at either side). In this particular case, to make sure that the InterlockedExchange(&v_,1) has completed before we continue.

  2. Because an InterlockedExchange would be less efficient (takes more interaction with any other cores in the machine to ensure all other processor cores have 'let go' of the value - which makes no sense, since most likely (in correctly working code) we only unlock if we actually hold the lock, so no other processor will have a different value cached than what we're writing over anyway), and a volatile write to the memory will be just as good.

于 2013-02-18T09:19:42.603 に答える
0

障壁は、メモリの同期を確保するためにあります。それらがないと、異なるスレッドが異なる順序でメモリの変更を確認する可能性があります。

前のInterlockedExchange値には関心がないため、2 番目のケースでは必要ありません。の役割は、 InterlockedExchange間違いなく、値を設定して前の値を返すことです。(そして、値しかとれず、 が私を超えているのに、なぜv_でしょう。)long01

于 2013-02-18T09:17:32.093 に答える
0

変数へのアトミック アクセスには 3 つの問題があります。まず、値の読み取りまたは書き込みの途中でスレッドの切り替えがないことを確認します。これが発生した場合、それは「引き裂き」と呼ばれます。2 番目のスレッドは部分的に書き込まれた値を見ることができますが、これは通常無意味です。第 2 に、すべてのプロセッサが書き込みによる変更を認識できるようにするか、値を読み取るプロセッサがその値に対する以前の変更を認識できるようにします。これは「キャッシュの一貫性」と呼ばれます。第 3 に、コンパイラが読み取りまたは書き込みをまたいでコードを移動しないようにします。これを「コードモーション」と呼びます。InterlockedExchange最初の 2 つを行います。MSDN のドキュメントはやや混乱_ReadWriteBarrierしていますが、3 番目、場合によっては 2 番目を行います。

于 2013-02-18T15:01:14.713 に答える