_InterlockedCompareExchange128 funzioni intrinseche
Sezione specifica Microsoft
Esegue un confronto e uno scambio interlock a 128 bit.
Sintassi
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
);
Parametri
Destinazione
[in, out] Puntatore alla destinazione, ovvero una matrice di due interi a 64 bit considerati come campo a 128 bit. I dati di destinazione devono essere allineati a 16 byte per evitare un errore di protezione generale.
ExchangeHigh
[in] Intero a 64 bit che può essere scambiato con la parte alta della destinazione.
ExchangeLow
[in] Intero a 64 bit che può essere scambiato con la parte bassa della destinazione.
ComparandResult
[in, out] Puntatore a una matrice di due interi a 64 bit (considerato come campo a 128 bit) da confrontare con la destinazione. Nell'output, questa matrice viene sovrascritta con il valore originale della destinazione.
Valore restituito
1 se il comparand a 128 bit è uguale al valore originale della destinazione. ExchangeHigh
e ExchangeLow
sovrascrivere la destinazione a 128 bit.
0 se il comparand non è uguale al valore originale della destinazione. Il valore della destinazione è invariato e il valore del comparand viene sovrascritto con il valore della destinazione.
Requisiti
Intrinsic | Architettura |
---|---|
_InterlockedCompareExchange128 |
x64, ARM64 |
_InterlockedCompareExchange128_acq , _InterlockedCompareExchange128_nf , _InterlockedCompareExchange128_rel |
ARM64 |
_InterlockedCompareExchange128_np |
x64 |
<File di intestazione intrin.h>
Osservazioni:
L'intrinseco _InterlockedCompareExchange128
genera l'istruzione cmpxchg16b
(con il lock
prefisso) per eseguire un confronto e uno scambio a 128 bit bloccati. Le versioni precedenti dell'hardware AMD a 64 bit non supportano questa istruzione. Per verificare la presenza del supporto hardware per l'istruzione cmpxchg16b
, chiamare l'intrinseco __cpuid
con InfoType=0x00000001 (standard function 1)
. Bit 13 di CPUInfo[2]
(ECX) è 1 se l'istruzione è supportata.
Nota
Il valore di ComparandResult
viene sempre sovrascritto. Dopo l'istruzione lock
, questo intrinseco copia immediatamente il valore iniziale di Destination
in ComparandResult
. Per questo motivo, ComparandResult
e Destination
deve puntare a posizioni di memoria separate per evitare comportamenti imprevisti.
Sebbene sia possibile usare _InterlockedCompareExchange128
per la sincronizzazione di thread di basso livello, non è necessario sincronizzare più di 128 bit se invece è possibile usare funzioni di sincronizzazione più piccole , ad esempio le altre _InterlockedCompareExchange
funzioni intrinseche. Usare _InterlockedCompareExchange128
se si vuole l'accesso atomico a un valore a 128 bit in memoria.
Se si esegue codice che usa l'intrinseco sull'hardware che non supporta l'istruzione cmpxchg16b
, i risultati sono imprevedibili.
Sulle piattaforme ARM usare le funzioni intrinseche con i suffissi _acq
e _rel
per la semantica di acquisizione e di rilascio, ad esempio all'inizio e alla fine di una sezione critica. Gli intrinseci ARM con un _nf
suffisso ("nessun recinto") non fungono da barriera di memoria.
Le funzioni intrinseche con suffisso _np
("nessuna prelettura") impediscono l'inserimento di una possibile operazione di prelettura da parte del compilatore.
Questa routine è disponibile solo come intrinseco.
Esempio
Questo esempio usa _InterlockedCompareExchange128
per sostituire la parola alta di una matrice di due interi a 64 bit con la somma delle parole elevate e basse e per incrementare la parola bassa. L'accesso BigInt.Int
alla matrice è atomico, ma questo esempio usa un singolo thread e ignora il blocco per semplicità.
// 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
Fine sezione specifica Microsoft
Vedi anche
Intrinseci del compilatore
_InterlockedCompareExchange funzioni intrinseche
Conflitti con il compilatore x86