0

MS VC++ Intrinsic InterlockedCompareExchange128 関数を使用しようとしています。

hello-world として、16 バイトのアドレスをそれ自体と比較し、それを別のものに置き換えようとしています。これはコンパイルされますが、機能しません。アドレスは新しい値と交換されません。const_cast を使用してコンパイルします (そうしないと、volatile をキャストできないことを叫びます)。

typedef struct t_node
{
    volatile __int64 arr[2];
}node;

int main()
{   

    node *a = new node();

    a->arr[0] = 100;
    a->arr[1] = 1;

    __int64 i = 200;
    __int64 j = 500;

    char r = _InterlockedCompareExchange128(a->arr, i,j, const_cast<__int64*>(&a->arr[0]));

    cout<<endl<<"Interlocked Compare Res: "<<r;

    cin.get();
    return 0;
}
4

1 に答える 1

4

ドキュメントから:

unsigned char _InterlockedCompareExchange128(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);

[入力、出力] ComparandResult
宛先と比較する 2 つの 64 ビット整数 (128 ビット フィールドと見なされる) の配列へのポインター。出力時に、これは destination の元の値で上書きされます

したがって、疑似コードでは次のようになります。

if(ComparandResult != Destination)
{
    temp = Destination
    Destination = ExchangeHigh:ExchangeLow
    ComparandResult = temp
}

Destination == ComparandResult(あなたのケース)が次の場合に何が起こるか:

if(ComparandResult != Destination)
{
    temp = Destination
    Destination = ExchangeHigh:ExchangeLow
    Destination = temp
}

これはノーです。
さらに、同じページにそのためのメモがあります。


ComparandResult の値は常に上書きされます。lock 命令の後、この組み込み関数はただちに Destination の初期値を ComparandResult にコピーします。このため、予期しない動作を避けるために、ComparandResult と Destination は別々のメモリ位置を指す必要があります。

于 2012-07-18T17:52:23.157 に答える