分享方式:


_InterlockedCompareExchange128內建函式

Microsoft 特定的

執行 128 位的相互鎖定比較和交換。

語法

unsigned char _InterlockedCompareExchange128(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_acq(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_nf(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_np(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_rel(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
);

參數

目的地
[in, out]目的地的指標,這是兩個視為 128 位欄位的 64 位整數陣列。 目的地資料必須對齊 16 位元組,以避免發生一般保護錯誤。

ExchangeHigh
[in]64 位整數,可與目的地的高部分交換。

ExchangeLow
[in]64 位整數,可以與目的地的低部分交換。

ComparandResult
[in, out]與目的地比較的兩個 64 位整數陣列指標(視為 128 位欄位)。 在輸出中,此陣列會以目的地的原始值覆寫。

傳回值

如果 128 位比較值等於目的地的原始值,則為 1。 ExchangeHighExchangeLow 會覆寫 128 位目的地。

如果比較值不等於目的地的原始值,則為 0。 目的地的值不變,而且比較值會覆寫為目的地的值。

需求

內建 架構
_InterlockedCompareExchange128 x64、ARM64
_InterlockedCompareExchange128_acq, _InterlockedCompareExchange128_nf, _InterlockedCompareExchange128_rel ARM64
_InterlockedCompareExchange128_np x64

標頭檔 < intrin.h>

備註

內部 _InterlockedCompareExchange128 函數會產生 cmpxchg16b 指令(前置 lock 詞),以執行 128 位鎖定的比較和交換。 舊版 AMD 64 位硬體不支援此指示。 若要檢查指示的硬體支援 cmpxchg16b ,請使用 呼叫 __cpuid 內建函式 InfoType=0x00000001 (standard function 1) 。 如果支援指示,則為 13 位 CPUInfo[2] 的 (ECX)。

注意

的值 ComparandResult 一律會覆寫。 指令 lock 之後,這個內建函式會立即將 的初始值 DestinationComparandResult 複製到 。 因此, ComparandResultDestination 應該指向不同的記憶體位置,以避免發生非預期的行為。

雖然您可以用於 _InterlockedCompareExchange128 低階執行緒同步處理,但如果您可以使用較小的同步處理函式(例如其他 _InterlockedCompareExchange 內建函式),則不需要同步處理超過 128 位。 如果您想要在記憶體中不可部分完成存取 128 位值,請使用 _InterlockedCompareExchange128

如果您在不支援 cmpxchg16b 指令的硬體上執行使用內建函式的程式碼,則結果無法預測。

在 ARM 平台上,搭配取得和釋放語意的 _acq_rel 字尾使用內建函式,例如在重要區段的開頭和結尾處。 具有 (「無柵欄」) 尾碼的 ARM 內部 _nf 函數不會作為記憶體屏障。

搭配 _np (「不預先擷取」) 字尾使用內建函式,可避免編譯器插入可能的預先提取作業。

此常式僅供內建使用。

範例

這個範例會使用 _InterlockedCompareExchange128 來取代兩個 64 位整數陣列的高字組和低字總和,並遞增低字。 陣列的存取是不可部分完成的 BigInt.Int ,但此範例會使用單一線程,並忽略鎖定以求簡單。

// cmpxchg16b.c
// processor: x64
// compile with: /EHsc /O2
#include <stdio.h>
#include <intrin.h>

typedef struct _LARGE_INTEGER_128 {
    __int64 Int[2];
} LARGE_INTEGER_128, *PLARGE_INTEGER_128;

volatile LARGE_INTEGER_128 BigInt;

// This AtomicOp() function atomically performs:
//   BigInt.Int[1] += BigInt.Int[0]
//   BigInt.Int[0] += 1
void AtomicOp ()
{
    LARGE_INTEGER_128 Comparand;
    Comparand.Int[0] = BigInt.Int[0];
    Comparand.Int[1] = BigInt.Int[1];
    do {
        ; // nothing
    } while (_InterlockedCompareExchange128(BigInt.Int,
                                            Comparand.Int[0] + Comparand.Int[1],
                                            Comparand.Int[0] + 1,
                                            Comparand.Int) == 0);
}

// In a real application, several threads contend for the value
// of BigInt.
// Here we focus on the compare and exchange for simplicity.
int main(void)
{
   BigInt.Int[1] = 23;
   BigInt.Int[0] = 11;
   AtomicOp();
   printf("BigInt.Int[1] = %d, BigInt.Int[0] = %d\n",
      BigInt.Int[1],BigInt.Int[0]);
}
BigInt.Int[1] = 34, BigInt.Int[0] = 12

END Microsoft 特定的

另請參閱

編譯器內建函式
_InterlockedCompareExchange內建函式
與 x86 編譯器衝突