2014-11-20 3 views
1

두 개의 8x 바이트 메모리 영역을 스왑해야합니다 (대부분 CMPXCHG8B을 사용). 그러나 가능한 한 빨리이 작업을 수행하려고합니다. 이 작업이 끝날 때까지 다른 스레드가 대기합니다. 나는 몇 가지 질문이 관련이 : 나는 복수를 프로세서, 또는 여러 코어을 사용하고있는 경우 LOCK 접두사에만 필요 Intel x86 CPU에서 CAS를 비교하고 가장 빨리 교체하는 방법은 무엇입니까?

가 결정됨

? 나는 가능하다면 이것을 사용하는 것을 정말로 피하고 싶다.

- 대기 스레드가 액세스하려는 메모리가 다른 캐시 라인에있는 경우 LOCK 접두어를 사용하지 않고 MESI 프로토콜을 기반으로 "잠금"할 수 있습니까?

단일 프로세서 (다중 코어)에서 실행 중이지만 차이점이있을 경우 멀티 프로세서 시스템과의 차이점을 가장 잘 설명하는 답변을 제공합니다.

+3

이 토론에서는 "processor"== "core"입니다. –

+3

'CMPXCHG8B'는 레지스터와 메모리를 스왑하기 때문에 두 개의 메모리 영역이 아니라는 점에서 많은 도움이 될 것이라고 생각합니다. 2 개의 연속 포인터 만 바꾸거나 뮤텍스를 사용해야 만 코드를 다시 작성할 수 있습니다. – Jester

답변

1

다중 프로세서 또는 다중 코어가 있고 공유 변수에 대한 안전한 액세스를 동기화하려는 경우 LOCK을 피할 수 없습니다. XCHG를 사용한다고해서 잠금을 피할 수는 없으며 명령에서 숨겨져 있습니다.

Jester의 힌트를 따라하면 두 개의 메모리 덩어리를 "왼쪽"과 "오른쪽"으로 명명하고 FLAG을 사용하여 동적으로 이름을 바꾸는 것이 좋습니다.

GetLeft: if LSB(FLAG) ; least significant bit 
       Read Left 
       else Read Right 

GetRight: if LSB(FLAG) 
       Read Right 
       else Read Left 

그런 다음, 다음 코드를 신속하게 수행 할 수 있습니다로에 대한 것 "교류"그들 :이 뮤텍스에 대한 필요성을 제거

SwapLeftAndRight: 
       LOCK INC FLAG ; flips LSB of flag 

. (스레드가 이 지역에 업데이트하려는 경우, 당신이 무엇을 하든지 상관없이 뮤텍스가 필요합니다.)

액세스 속도가 실제로 중요한 경우 LEFT 및 RIGHT에 대한 두 개의 연속 포인터를 스와핑하는 것에 대한 그의 힌트는 꽤 좋습니다.

+0

8 바이트 영역 쌍을 스왑 할 수도 있습니다. 하지만 그들은 연속적이어야하며 CPU는'cmpxchg16b' 명령 (64 비트 코드에서만 지원되며 일부 이전 64 비트 CPU에서는 지원되지 않음)을 지원해야합니다. – Brendan

+0

@ 브렌든 : 좋은 지적으로, 저는 단지 x86-32에 대해서 생각하고있었습니다. –

관련 문제