2016-08-14 3 views
0

Wiki에 따르면, CAS는 다음과 같이 수행어떻게 CAS 지침은 보장하지 자성

function cas(p : pointer to int, old : int, new : int) returns bool { 
    if *p ≠ old { 
     return false 
    } 
    *p ← new 
    return true 
} 

글쎄, 나를 위해 것을 여러 프로세서가 같은 인수 CAS 명령을 실행하려고 할 경우가있을 수 있음 동시에 여러 번의 쓰기 시도가 있으므로 어쨌든 그렇게하는 것이 안전하지 않습니다.

어디서 잘못 되었나요?

+1

동시에 여러 번 기록한 사람은 누가 이겼는지 분명하지 않은 한 문제가되지 않습니다. 안전을 위해 추가적인 처리가 필요한 [ABA 문제] (https://en.m.wikipedia.org/wiki/ABA_problem)를 생각할 수도 있습니다. 그러나 int의 경우에는 문제가되지 않습니다. – Voo

+0

@Voo "동시에 여러 번 쓰는 것이 문제가되지 않습니다."- 확실합니까? 예를 들어, x86은 정렬되지 않은 DWORD에 대한 쓰기의 원자 성을 보장하지 않기 때문에 안전하지 않다고 생각했습니다. – FrozenHeart

답변

2

동시에 여러 코어에서 수행되는 원자 읽기 - 비교 - 쓰기 명령어 do은 서로 경쟁하지만 하드웨어를 고려해야합니다. Hardware arbitration of atomic RMW instructions은 현대 CPU의 진짜이며, 어느 정도의 공정성을 제공하여 lock cmpxchg에 회전하는 한 스레드가 동일한 작업을 수행하는 다른 스레드를 완전히 차단하지 못하게합니다. (비록 나쁜 설계인데, 획득로드를 회전시키고 성공해야만 CAS를 수행하는 것이 더 좋습니다.)

어떤 순서로 발생하는지 보장 할 수 없으므로 다음과 같은 사항을 신중하게 고려해야합니다. 정확성은 비교 - 교환이 원자 적이라는 것에 달려 있습니다. (ABA problem은 일반적인 함정입니다).


BTW, 의사의 그 블록 전체는 단일 원자 조작으로 일어난다. 단일 원자 연산으로 읽기 - 비교 - 쓰기 또는 읽기 - 수정 - 쓰기를 수행하는 것은 MESIF/MOESI가 잘 처리하는 점포보다 하드웨어에 훨씬 더 어렵습니다.

틀림 없습니까? 나는 그것이 예를 들어, 86 비 정렬 DWORD에 대한 쓰기의 원 자성을 보장하지 않습니다, 때문에

lock cmpxchg에 관계없이 정렬의 원자 작업을 만드는 것을 할 안전하다고 생각했다. 특히 단일 캐시 라인을 원자 적으로 수정하는 것만으로는 충분하지 않은 캐시 라인 분할에서 정렬되지 않은 경우 속도가 느려질 수 있습니다.

도 참조하십시오. Atomicity on x86 여기서는 조작이 원자 적이어야 함을 의미하는 것을 설명합니다.

+0

'CMPXCHG' 명령을 사용하는 것만으로 충분하지 않습니까? 'LOCK '접두사로 표시해야합니까? – FrozenHeart

+1

@FrozenHeart : 원할 경우 '잠금'이 필요합니다! 'lock '은 메모리 피연산자가있는'xchg'에는 암시 적이지만, 다른 명령에는 암묵적이지 않습니다. –

+0

그래서'CAS' 자체만으로는 원 자성을 제공하기에 충분하지 않으므로 접두어 앞에 LOCK 접두어를 붙여야합니다. 그때'CMPXCHG'와 같은 지시를받는 것은 무엇입니까? 우리가 그 당시에 오직 한 ** 지시 만 '잠그기'때문에? – FrozenHeart

1

위키를 읽으면 게시 한 코드의 CAS가 "다음 의사 코드의 원자 버전입니다"라고 말합니다. Atomic은 다른 스레드의 중단없이 코드가 실행됨을 의미합니다. 따라서 여러 스레드가 동일한 코드 (사용자가 제안한 것과 같은)로이 코드를 동시에 실행하려고 시도하더라도 실제로는 원 자성이 별도로 실행해야하기 때문에 실제로 실행되지 않기 때문에 그 중 하나만 true를 반환합니다.

"x86은 정렬되지 않은 DWORD에 대한 쓰기의 원 자성을 보장하지 않습니다"라고 말했기 때문에 여기서는 cas 함수의 원자 속성 때문에 문제가되지 않습니다.

관련 문제