내장 함수 _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입니다. 대상 값은 변경되지 않으며 비교값은 대상 값으로 덮어씁니다.
요구 사항
Intrinsic | 아키텍처 |
---|---|
_InterlockedCompareExchange128 |
x64, ARM64 |
_InterlockedCompareExchange128_acq , , _InterlockedCompareExchange128_nf _InterlockedCompareExchange128_rel |
ARM64 |
_InterlockedCompareExchange128_np |
X64 |
헤더 파일<intrin.h>
설명
내장 함수는 _InterlockedCompareExchange128
128비트 잠긴 비교 및 교환을 수행하는 명령(lock
접두사 포함)을 생성 cmpxchg16b
합니다. AMD 64비트 하드웨어의 초기 버전은 이 지침을 지원하지 않습니다. 명령에 대한 cmpxchg16b
하드웨어 지원을 확인하려면 intrinsic을 호출 __cpuid
합니다 InfoType=0x00000001 (standard function 1)
. 명령이 지원되는 경우 ECX(비트 13 CPUInfo[2]
)는 1입니다.
참고 항목
값 ComparandResult
은 항상 덮어씁니다. 명령 후에 lock
이 내장 함수는 초기 값을 Destination
즉시 복사합니다 ComparandResult
. 이러한 이유로 ComparandResult
Destination
예기치 않은 동작을 방지하기 위해 별도의 메모리 위치를 가리킵니다.
하위 수준 스레드 동기화에 사용할 _InterlockedCompareExchange128
수 있지만 더 작은 동기화 함수(예: 다른 _InterlockedCompareExchange
내장 함수)를 대신 사용할 수 있는 경우 128비트 이상 동기화할 필요가 없습니다. 메모리의 128비트 값에 원자성 액세스를 원하는 경우 사용합니다 _InterlockedCompareExchange128
.
명령을 지원하지 cmpxchg16b
않는 하드웨어에서 내장 함수를 사용하는 코드를 실행하면 결과를 예측할 수 없습니다.
ARM 플랫폼에서는 임계 영역의 시작 및 끝과 같은 위치에서 의미 체계를 획득하고 해제하려면 _acq
및 _rel
접미사가 포함된 내장 함수를 사용합니다. ("no fence") 접미사가 있는 _nf
ARM 내장 함수는 메모리 장벽으로 작동하지 않습니다.
_np
("no prefetch"의 약어) 접미사가 포함된 내장 함수는 컴파일러가 가능한 프리페치 연산을 삽입하지 못하도록 차단합니다.
이 루틴은 내장 함수로만 사용할 수 있습니다.
예시
이 예제에서는 두 개의 64비트 정수 배열의 상위 단어를 높음과 낮음 단어의 합계로 바꾸고 낮은 단어를 증분하는 데 사용합니다 _InterlockedCompareExchange128
. 배열에 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
Microsoft 전용 종료