문제

어떤 상황에서 x86에서 동일한 배열의 인접 요소에 동시에 두 개의 다른 스레드를 동시에 쓰는 것이 안전하지 않습니까? 미친 메모리 모델이있는 DS9K와 같은 아키텍처에서는 단어가 찢어 질 수 있지만 X86 단일 바이트는 주소가 줄어 듭니다. 예를 들어, D 프로그래밍 언어에서 real x86의 80 비트 부동 소수점 유형입니다. 다음과 같은 일을하는 것이 안전할까요?

real[] nums = new real[4];  // Assume new returns a 16-byte aligned block.
foreach(i; 0..4) {
    // Create a new thread and have it do stuff and 
    // write results to index i of nums.
}

참고 : 이것이 안전하더라도 캐시와의 잘못된 공유 문제를 일으켜 성능이 느려질 수 있습니다. 그러나, 내가 염두에두고있는 사용 사례의 경우 실제로는 문제가되지 않기 때문에 충분히 드물게 될 것입니다.

편집 : 작성된 값을 다시 읽는 것에 대해 걱정하지 마십시오. 가정은 거기에 있다는 것입니다 ~ 할 것이다 값을 읽기 전에 동기화하십시오. 나는 안전에만 관심이 있습니다 글쓰기 이런 식으로.

도움이 되었습니까?

해결책

X86에는 일관된 캐시가 있습니다. 캐시 라인에 쓰는 마지막 프로세서는 모든 것을 획득하고 캐시에 쓰기를합니다. 이를 통해 해당 값에 기록 된 단일 바이트 및 4 바이트 값이 원자 적으로 업데이트됩니다.

"안전"과 다릅니다. 프로세서가 각각 디자인으로 해당 프로세서가 "소유 한"바이트/dword에만 쓰면 업데이트가 정확합니다. 실제로 한 프로세서가 다른 프로세서가 다른 사람이 작성한 값을 읽기를 원하며 동기화가 필요합니다.

또한 "효율적"과 다릅니다. 여러 프로세서가 각각 캐시 라인의 다른 위치에 쓸 수 있다면 캐시 라인은 CPU 사이에 핑을 할 수 있으며 캐시 라인이 단일 CPU로 이동하여 거기에 머무는 경우보다 훨씬 비쌉니다. 일반적인 규칙은 프로세서 별 데이터를 자체 캐시 라인에 넣는 것입니다. 물론, 한 단어 만 한 번만 글을 쓰려고하고 캐시 라인 이동에 비해 작업량이 중요하다면 성능이 허용됩니다.

다른 팁

나는 무언가를 놓치고 있을지 모르지만 어떤 문제도 예측하지 않습니다. X86 아키텍처는 필요한 것만 쓰고 지정된 값 외부에서 글을 쓰지 않습니다. 캐시 스누핑은 캐시 문제를 처리합니다.

당신은 x86 세부 사항에 대해 묻고 있지만, 당신의 예는 일부 고급 언어입니다. D에 대한 귀하의 구체적인 질문은 사용중인 컴파일러 또는 D 언어 사양을 작성한 사람들 만 답변 할 수 있습니다. 예를 들어 Java는 어레이 요소 액세스가 찢어지지 않아야합니다.

X86과 관련하여, 작전 원자는 8.1 절에 지정됩니다. 인텔의 소프트웨어 개발자의 매뉴얼 볼륨 3A. 그것에 따르면, 원자 매장 작업에는 다음이 포함됩니다. 바이트 저장, 단어로 정렬 된 단어 및 dword 정렬 DWORD는 모든 X86 CPU에 저장합니다. 또한 캐시 라인 내의 캐시 메모리에 대한 P6 및 이후 CPU에서 정렬되지 않은 16, 32 및 64 비트 액세스가 원자임을 지정합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top