다음을 통해 공유


내장 함수 _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입니다. 대상 값은 변경되지 않으며 비교값은 대상 값으로 덮어씁니다.

요구 사항

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 전용 종료

참고 항목

컴파일러 내장 함수
내장 함수 _InterlockedCompareExchange
x86 컴파일러와 충돌