2012-03-15 3 views
10

16 바이트를 원자 적으로 읽고 쓸 필요가 있습니다. 필자는 cmpxchg16을 사용하여서만 작업을합니다.이 작업은 하나의 모호한 AMD 프로세서를 제외하고 모든 x64 프로세서에서 사용할 수 있습니다.x64 CPU에서 원자 16 바이트 읽기

이제 16 비트의 정렬 된 값에 대해서만 질문합니다. 전체 메모리 장벽처럼 작동하는 cmpxchg16을 사용하여 수정 한 경우 이전 절반의 데이터와 절반의 새 데이터 인 16 바이트 위치를 읽을 수 있습니까?

SSE 명령어로 읽는 한 (읽기가 진행되는 동안 스레드가 중단 될 수 없기 때문에) 일관성없는 데이터를 읽기 위해 읽기가 불가능하다는 것을 (멀티 프로세서 numa 시스템에서도) 생각합니다. 원자가되어야한다고 생각합니다.

cmpxchg16이 실행될 때 다른 스레드가 중간에 읽을 가능성이있는 두 개의 8 바이트 블록을 쓰는 것이 아니라 원자 적으로 16 바이트를 수정한다는 가정을하고 있습니다. (정직하게는 어떻게 보입니까? 원자가 아닌 경우 작동 할 수 있습니다.)

맞습니까? 내가 틀렸다면 잠금을 사용하지 않고 원자 16 바이트 읽기를 수행하는 방법이 있습니까?

참고 : couple similar questions here이 있지만 cmpxchg16 만 사용하여 기록하는 경우는 다루지 않으므로이 질문은 답변이없는 별도의 질문이라고 생각합니다.

편집 : 사실 내 생각에는 잘못된 것 같습니다. SSE로드 명령어는 두 개의 64 비트 읽기로 실행될 수 있으며 cmpxchg16이 다른 프로세서에 의한 두 가지 읽기 사이에서 실행될 수 있습니다.

+1

같은 간단한 평가 즉 그들은 원자 아니다. CMPXCHG16B를 사용하여 씁니다. 읽기 또한 원자 적이어야하거나 일치하지 않는 데이터가 나타날 수 있습니다. AFAIK 당신의 유일한 선택은 CMPXCHG16B로 읽는 것입니다. – Timo

+0

예, 저는 읽기 사이에 스레드가 중단되지 않도록해야한다는 실수를했습니다. 그러나 실제 버스 작업 자체는 여전히 인터리브 될 수 있습니다. – Eloff

+0

읽기에 cmpxchg16b를 사용하면 느려질 수 있습니다. 그러나 25 % 더 많은 메모리를 사용함으로써 Dmitry Vyukov의 hashmap과 같은 seqlock 스타일의 접근법을 수행 할 수 있습니다 : http://www.1024cores.net/home/downloads – Eloff

답변

9
typedef struct 
{ 
    unsigned __int128 value; 
} __attribute__ ((aligned (16))) atomic_uint128; 

unsigned __int128 
atomic_read_uint128 (atomic_uint128 *src) 
{ 
    unsigned __int128 result; 
    asm volatile ("xor %%rax, %%rax;" 
       "xor %%rbx, %%rbx;" 
       "xor %%rcx, %%rcx;" 
       "xor %%rdx, %%rdx;" 
       "lock cmpxchg16b %1" : "=A"(result) : "m"(*src) : "rbx", "rcx"); 
    return result; 
} 

그 트릭을해야합니다. typedef는 올바른 정렬을 보장합니다. cmpxchg16b은 데이터가 16 바이트 경계에 정렬되어야합니다.

cmpxchg16b는 *src에 0이 포함되어 있는지 테스트하고 그럴 경우 0으로 만듭니다 (nop). 두 경우 모두 올바른 값은 나중에 RAX : RDX에 표시됩니다. 상기

코드는 이미, SSE 읽기 16 바이트는 다수의 메모리 액세스를 사용하여 구현 될 수있는 연동 질문에 답변하고

push %rbx 
xor %rax,%rax 
xor %rbx,%rbx 
xor %rcx,%rcx 
xor %rdx,%rdx 
lock cmpxchg16b (%rdi) 
pop %rbx 
retq 
+0

예,이 방법을 사용해야한다고 생각합니다.이제는 간단한 SSE로드가 두 개의 64 비트 읽기로 분할 될 수 있고 cmpxchg16이 잠재적으로 읽기간에 발생할 수 있다는 사실이 나에게 발생합니다. – Eloff

1

참고 문헌에 따르면 http://siyobik.info/main/reference/instruction/CMPXCHG8B%2FCMPXCHG16BCMPXCHG16 원자 기본적 아니지만, 기본적으로 데이터가 판독 내에 변경 및 위상을 작성할 수 있음을 의미 LOCKhttp://siyobik.info/main/reference/instruction/LOCK

를 이용하여 원자 할 수있다. 잠금은 읽기 및 쓰기 원자 모두를 만듭니다.

+0

"CMPXCHG16B는 대상 (메모리) 피연산자가 16 바이트 정렬 . " – kay

+0

죄송합니다. 잠금 접두사가있는 cmpxchg16을 의미합니다. 그러나 잠금은 SSE 명령어와 함께 사용할 수 없습니다. – Eloff