1


<sys/atomic.h> で SunOs によって提供されるアトミック操作を使用しています。これは
void *atomic_cas_ptr(volatile void *target, void *cmp, void *newval);

現在使用可能になっています。この関数によって返され、呼び出し先関数 cmp によって渡された古い値が同じかどうかを確認する必要があります。成功しています。
しかし、私には疑問があります: この関数は古い値への void ポインターを返すので、それを void *old と呼び、void *cmp を渡します。次に、これら 2 つの old と cmp を比較する必要があります。この二つ ?比較中に*oldが変更された場合、私は何をするつもりですか?
本質的に私がやりたいことは、これらの 3 つの引数を取り、成功または失敗を示す true または false を返す別の関数内で、この関数をワープすることです。
関してCAS、最終的にはハードウェアでロックを取得するため(バスでロック)、ロックフリー操作と呼ぶのは誤称だと読みましたが、正しいですか?そのため、CAS はコストのかかる操作です。

4

1 に答える 1

2

おそらく、関数宣言があなたを混乱させました。この関数は古い値 (何の?) へのポインターを返すのではなく、target(これは実際には void* へのポインター、つまりvoid* volatile * target) が指すメモリーからの古い値を返します。

通常、CAS プリミティブが bool ではなく古い値を返す場合、次のような方法で CAS の成功を確認します。

void* atomic_ptr; // global atomically modified pointer

void* oldval, newval, comparand; // local variables
/* ... */
oldval = atomic_cas_ptr( (void*)&atomic_ptr, /* note that address is taken */
                          comparand, newval );
if( oldval == comparand ) {
    // success
} else {
    // failure
}

そのため、old_val と comparand を比較するときは、同時に変更されないローカル変数を操作し (グローバルの atom_ptr は再び変更される可能性があります)、逆参照せずにポインター値を比較します。

必要な関数は次のようになります。

bool my_atomic_cas_ptr(volatile void* target, void* comparand, void* newval)
{
    return (comparand == atomic_cas_ptr(target, comparand, newval));
}

一部のアルゴリズムでは古い値 (CAS の前の値) がわかっている必要があるため、bool ではなく古い値を返す CAS プリミティブを使用する方がよいことに注意してください。複雑で非効率的です ( bool を返すMacOS CAS プリミティブから正しい古い値を取得しようとする次のコードを参照してください)。

void* CAS(void* volatile* target, void* comparand, void* newval)
{
    while( !OSAtomicCompareAndSwapPtr(comparand, newval, target) ) {
        void* snapshot = *target;
        if( snapshot!=comparand ) return snapshot;
    }
    return comparand;
}

CAS ロックメモリバスに関しては、ハードウェアに依存します。これは古い x86 プロセッサには当てはまりましたが、最新の x86 システムでは異なります。まず、中央バスがありません。AMD の HyperTransport と Intel の QuickPath Interconnect に置き換えられました。第 2 に、最近の CPU 世代では、ロックされた命令がすべてシリアル化されているわけではありません (別のメモリ アドレスでロックされた命令が干渉しないことを示すデータを参照してください)。そして最後に、一般的に受け入れられている定義では、ロックの自由はシステム全体の進行を保証するものであり、同期のシリアル化がないことではありません。

于 2011-06-18T20:11:34.917 に答える