2017-04-22 23 views
3

문제를 간단하게 유지하고 내 문제의 핵심에 집중하기 위해 포인터 변수 ptr에 의해 로컬로 지정된 메모리 위치가 여러 프로세스에서 공유된다고 가정 해 봅시다. 나는 특히 C/++의 MPI 공유 메모리 윈도우를 사용하여 메모리를 할당하고 공유한다. 구체적으로, 특정 공유 메모리 쓰기 작업 (MPI)의 동기화

float* ptr; 

지금 모든 프로세스가 const float f ptr이 할 수있는 동일한 값을 쓰려고한다고 가정

그래서 로컬 우리는 내 질문은 즉

*ptr = f; 

,이,의는 ptr 참조에게 부동 소수점 변수를 가정 해 봅시다 : 모든 프로세스가 동일한 방식으로 바이트를 수정하려고 시도 할 때 (즉, f이 모든 프로세스에 대해 동일한 값을 갖는다는 점을 고려할 때),이 작업에는 동기화가 필요하거나 동시에 실행될 수 있습니까? 따라서 내 질문은 다음과 같이 요약됩니다. 부동 소수점 변수를 사용하면 모든 프로세스가 동일한 방식으로 메모리를 수정하려고해도 경쟁 조건으로 인해 일치하지 않는 바이트 패턴이 발생할 수 있습니다. 나는. 모든 프로세스가 동일한 데이터를 쓰는 것을 알고 있다면 동기화를 생략 할 수 있습니까?

답변

1

예, 공유 메모리를 동기화해야합니다. 수정 스레드가 다른 프로세스에 상주한다는 사실은 의미가 없으며, 여전히 데이터 경쟁 (다른 스레드에서 공유 메모리에 쓰기)입니다.

가시성 및 메모리 재정렬과 같은 동기화 객체가 해결하는 다른 문제가 있지만 공유 메모리에 쓰여지는 내용은 적합하지 않습니다.

현재 표준은 프로세스 (스레드)의 개념을 정의하지 않으며 프로세스 간 동기화를위한 수단을 제공하지 않습니다.

공유 메모리에 std::mutex을 할당하고이를 동기화 프리미티브로 사용하거나 뮤텍스, 세마포어 또는 이벤트와 같은 win32 프로세스 간 동기화 프리미티브에 의존하십시오.

또는 프리미티브를 동기화하려는 경우 std::atomic<T>을 공유 메모리에 할당하여 동기화 된 프리미티브로 사용할 수 있습니다.

+0

답변 해 주셔서 감사합니다."서로 다른 프로세스에서 크기를 조정하는 것"이 ​​의미하는 바를 더 자세히 말할 수 있습니까? MPI에서 적절한 동기화를 구현 한 경우 (확실한 방법을 알고 있음), 동기화 객체를 사용하지 않습니다. 그래서 나는 "가시성, 메모리 재정렬"이 어떻게 영향을 미치는지 이해하지 못한다. 문제를 해결하기 위해 C++ 표준 라이브러리 기능을 사용하지는 않을 것입니다. 충돌은 스레드가 아닌 데이터에 액세스하는 다른 프로세스 사이에서 발생한다는 점에 유의하십시오. – sperber

+0

오타입니다. "거주"합니다. MPI가 동기화를 제공하는 경우 이는 다른 질문입니다. 예를 들어 예를 들어 답했습니다. 서로 다른 프로세스에서 벌거 벗은 포인터에 쓰기 –

+0

동일한 데이터를 쓰는 여러 프로세스 (예 : 어셈블리 수준에서 잘못 될 수있는)로 메모리를 다시 정렬 할 때 무엇이 ​​잘못 될 수 있습니까? – sperber

1

C++에서 동기화 프리미티브 또는 원자 연산을 적절하게 사용하지 않고 여러 프로세스가 동일한 메모리 위치에 쓰는 경우 정의되지 않은 동작이 발생합니다. 즉, 작동 할 수도 있고 작동하지 않을 수도 있습니다. 컴퓨터가 작동하지 않을 수도 있습니다.

실제로 컴퓨터에서는 작동한다고 생각하는 방식으로 작동한다는 것이 확실합니다. 실제로 아키텍처에 따라서는 예상대로 작동하지 않을 가능성이 있습니다 : CPU가 공유 값만큼 메모리 블록을 읽거나 쓸 수 없거나 공유 값의 저장이 정렬 경계를 넘는 경우 그러한 쓰기는 실제로는 읽기와 관련 될 수 있으며, 읽기 - 수정 - 쓰기는 메모리의 다른 변경을 되돌 리거나 손상시키는 효과를 가질 수 있습니다.

당신이 원하는 것을 얻을 수있는 가장 쉬운 방법은 "편안한"원자 작업으로 쓰기 작업을 수행하는 것입니다 : 쓰기는 데이터가 발생하지 않는 의미에서 "원자"는 것을 보장

std::atomic_store_explicit(ptr, f, std::memory_order_relaxed); 

경쟁을 피할 수 있으며, *ptr = f과 관련된 잠재적 인 문제가있는 아키텍처를 제외하고는 오버 헤드가 발생하지 않습니다.

+0

우수 답변, 고맙습니다. 이것들은 제가 찾고있는/발견 한 세부 사항과 힌트입니다. – sperber

+0

이것은 'memory_order_relaxed'가 실제로 좋은 생각 인 상황은 매우 드뭅니다. 일반적으로 공유 메모리에 대한 모든 액세스는 동기화 프리미티브로 보호되거나보다 강력한 메모리 순서로 수행되어야합니다. – Sneftel