2013-05-21 3 views
1

저는 2 대의 컴퓨터가 32 비트 PCI 버스를 통해 동일한 메모리에 액세스하는 다중 컴퓨터 환경에서 작업하고 있습니다.다중 컴퓨터 메모리에서 원 자성 보유 읽기/쓰기를 수행합니까?

첫 번째 컴퓨터는 32 비트 int에만 쓰기 만합니다.
*int_pointer = number;

두 번째 컴퓨터는 32 비트 int에서만 읽습니다.
number = *int_pointer;

OS/CPU는 모두 32 비트 아키텍처입니다.
PCI 기반 컴퓨터는 Intel 기반입니다.
PCI 카드의 컴퓨터가 전원이 켜져 있습니다.

필자가 우려하는 경우는 읽기 전용 컴퓨터가 읽기 전용 컴퓨터와 동시에 변수를 변경하면 읽기 컴퓨터의 잘못된 데이터가 발생한다는 것입니다.
메모리의 동일한 위치에 읽기/쓰기의 원 자성이 여러 컴퓨터에서 유지되는지 알고 싶습니다.

그렇다면 것 다음 방지 경쟁 조건 :

number = *int_pointer; 
while(*int_pointer != number) { 
    number = *int_pointer; 
} 

내가 * 모든 16ms를 발생 기록하고 무작위로 발생합니다 읽기 것을 보장 할 수 있습니다.

두 컴퓨터가 서로 다른 타이머를 사용하므로 * 시간이 흐려질 수 있습니다.

+7

를 참조하십시오. – paxdiablo

+0

이 PCI 버스의 메모리 컨트롤러는 무엇입니까/누가 있습니까? –

+0

@JonathonReinhart 메모리 컨트롤러는 두 번째 컴퓨터가 상주하는 PCI 카드입니다. pax, 사실 일 수도 있지만 내가 사용하는 언어는 C입니다. – Serdalis

답변

0

내 질문에 답변 :

경쟁 조건이 없습니다. 외부 PCI 장치의 메모리 컨트롤러는 모든 메모리 읽기/쓰기 작업을 처리합니다. 모든 데이터 캐리어가 최소 32 비트이기 때문에 32 비트 내에 경쟁 조건이 없습니다.

DMA 컨트롤러를 사용하기 때문에 메모리와 프로세서 간의 상호 작용이 잘 작동합니다.

이는 구조 자체와는 C와는 아무 모든 것을 (그리고 아키텍처의 "32 비트"설명 정말 충분를 결정하는 것입니다)이없는 Direct Memory Access -PCI

2

이 답변에 대한 정보가 충분하지 않습니다.

어느 CPU가 메모리를 *int_pointer에 캐시하기로 결정하면이 오류는 항상 실패하고 여분의 코드로 인해 경쟁 조건이 수정되지 않습니다. 두 개의 CPU 가정

*int_pointer에서 메모리, 위치 *int_pointer는 PCI 카드의 CPU는 32 비트의 메모리 인터페이스를 AND 4 바이트/32 비트 경계에 정렬되도록, 캐시 불가능한 것을 알 AND 포인터가 volatile에 대한 포인터로 선언되어 있으면 두 C 컴파일러 모두 올바르게 volatile을 구현합니다. 그러면 업데이트가 원자 일 가능성이 높습니다.

위 조건 중 하나라도 충족되지 않으면 결과를 예측할 수 없으며 "경주 감지"코드가 작동하지 않을 수 있습니다. volatile가가 필요한 이유

편집

설명합니다 :

여기 당신의 경쟁 조건의 -O4와 MIPS 어셈블러로 컴파일 된 코드없이 volatile 규정 자입니다. (생성 된 코드는 86 코드보다 쉽게 ​​읽을 때문에 MIPS를 사용)

int nonvol(int *ip) { 
    int number = *ip; 
    while (*ip != number) { 
    number = *ip; 
    } 
    return number; 
} 

분해 출력 : *ip 변경할 수 없다는 것을 알고 이후

 00000000 <nonvol>: 
    0: 8c820000  lw  v0,0(a0) 
    4: 03e00008  jr  ra 

컴파일러는 while 루프 얻어 최적화했습니다.

여기 volatile로 발생과 같은 컴파일러 옵션 내용은 다음과 같습니다

int vol(volatile int *ip) { 
    int number = *ip; 
    while (*ip != number) { 
    number = *ip; 
    } 
    return number; 
} 

분해 출력 : 이제 while 루프 멀리 최적화되지

 00000008 <vol>: 
    8: 8c820000  lw  v0,0(a0) 
    c: 8c830000  lw  v1,0(a0) 
    10: 1443fffd  bne  v0,v1,8 <vol> 
    14: 00000000  nop 
    18: 03e00008  jr  ra 

volatile를 사용하여 컴파일러에게 있기 때문에 그 *ip 수 언제든지 변경하십시오.

+0

int가 4 바이트 경계에 정렬되고 PCI 카드의 CPU가 32 비트입니다. 경쟁 조건 코드는 읽는 동안 발생하는 변경 사항을 감지하고 결과를 비교하여이를 확인하는 방법입니다 (존재하는 경우). 휘발성은이 시나리오에 영향을 미치지 않으며 가리키는 메모리는 일반적으로 어쨌든 캐시되지 않습니다. 그러나 공유 메모리에 대한 읽기가 없기 때문에 캐시가 실제로이 시나리오가 발생하지 않도록합니다. – Serdalis

+1

휘발성은 절대적으로 상황에 영향을 미칩니다. 당신이 그것을 기각하기 전에 당신은 완전히 이해해야합니다. –

+0

에는 휘발성이 필요한 이유를 설명하는 몇 가지 예제 코드가 추가되었습니다. – markgz

관련 문제