_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。 ExchangeHigh
和 ExchangeLow
會覆寫 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
之後,這個內部函數會立即將 的初始值Destination
ComparandResult
複製到 。 因此, ComparandResult
和 Destination
應該指向不同的記憶體位置,以避免發生非預期的行為。
雖然您可以用於 _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 特定的