메모리 장벽

Memory barrier

컴퓨팅에서 메모리 장벽은 멤바, 메모리 펜스 또는 펜스 명령으로도 알려져 있으며 중앙처리장치(CPU) 또는 컴파일러가 장벽 명령 전후에 발행된 메모리 동작에 대해 순서 제한을 강제하도록 하는 장벽 명령의 일종입니다.이는 일반적으로 장벽 이전에 발행된 운영이 장벽 이후에 발행된 운영 이전에 수행될 것을 보장한다는 것을 의미한다.

대부분의 최신 CPU는 성능 최적화를 채택하고 있기 때문에 메모리 장벽이 필요합니다.이것에 의해, 순서가 어긋나는 실행이 발생할 가능성이 있습니다.이러한 메모리 조작(로드 및 스토어)의 순서 변경은, 통상, 1 스레드의 실행에서는 눈에 띄지 않지만, 주의 깊게 제어하지 않는 한, 동시 프로그램이나 디바이스 드라이버로 예측할 수 없는 동작이 발생할 가능성이 있습니다.순서 제약의 정확한 성질은 하드웨어에 의존하며 아키텍처의 메모리 순서 모델에 의해 정의됩니다.일부 아키텍처는 서로 다른 주문 제약을 적용하기 위한 여러 장벽을 제공합니다.

메모리 장벽은 일반적으로 여러 디바이스가 공유하는 메모리에서 작동하는 낮은 수준의 기계 코드를 구현할 때 사용됩니다.이러한 코드에는 멀티프로세서 시스템의 동기화 프리미티브와 잠금 없는 데이터 구조 및 컴퓨터 하드웨어와 통신하는 장치 드라이버가 포함됩니다.

프로그램이 싱글 CPU 머신 상에서 실행되면 하드웨어는 모든 메모리 조작이 프로그래머에 의해 지정된 순서(프로그램 순서)로 실행된 것처럼 프로그램이 실행되도록 하기 위해 필요한 부기를 수행합니다.따라서 메모리 장벽은 필요하지 않습니다.단, 멀티프로세서시스템 내의 다른 CPU나 메모리 매핑된 주변기기 등 여러 디바이스와 메모리를 공유하고 있는 경우에는 순서가 다른 액세스가 프로그램 동작에 영향을 줄 수 있습니다.예를 들어 제2CPU는 제1CPU에 의해 이루어진 메모리 변경을 프로그램 순서와 다른 순서로 볼 수 있다.

프로그램은 멀티스레드 가능한 프로세스(하드웨어 스레드와는 대조적으로 pthread 등의 소프트웨어 스레드)를 통해 실행된다.다른 프로세스는 메모리 공간을 공유하지 않기 때문에 이 설명은 각각 다른 프로세스로 실행되는 두 프로그램(따라서 다른 메모리 공간)에는 적용되지 않습니다.1개의 프로세스(즉, 복수의 소프트웨어 스레드가 1개의 메모리 공간을 공유하는 1개의 메모리 공간)로 실행되는 2개 이상의 (소프트웨어)스레드에 적용됩니다.멀티코어 프로세서에서 여러 소프트웨어 스레드를 동시에 실행할 수 있습니다.

멀티코어 프로세서에서 실행되는 다음 멀티스레드 프로그램은 이러한 순서가 잘못된 실행이 프로그램 동작에 어떻게 영향을 미치는지 보여 줍니다.

처음에 메모리 위치x그리고.f둘 다 가치가 있다0프로세서 넘버 1에서 동작하는 소프트웨어 스레드가 루프하는 동안f0 이 되고 나서, 값이 출력됩니다.x프로세서 #2에서 실행되고 있는 소프트웨어 스레드는 값을 저장합니다.42안으로x그리고 그 값을 저장합니다.1안으로f2개의 프로그램 fragment에 대한 의사 코드를 다음에 나타냅니다.

프로그램의 순서는, 개개의 CPU 의 순서에 대응합니다.

스레드 #1 코어 #1:

 하는 동안에 (f == 0);  // 메모리 펜스가 필요합니다.  인쇄물 x; 

스레드 #2 코어 #2:

 x = 42;  // 메모리 펜스가 필요합니다.  f = 1; 

인쇄문이 항상 숫자 "42"를 인쇄하는 것을 기대할 수 있습니다. 그러나 스레드 #2의 스토어 조작이 순서대로 실행되지 않으면 다음 작업이 가능합니다.f전에 갱신되다 x따라서 인쇄문은 "0"으로 출력될 수 있습니다.마찬가지로 스레드 #1의 로드 조작이 순서대로 실행되지 않을 수 있으며, 이는x읽히다 f체크되어 있기 때문에, 인쇄문이 예기치 않은 값을 인쇄하는 경우가 있습니다.대부분의 프로그램에서 이러한 상황은 허용되지 않습니다.스레드 #2의 할당 전에 메모리 장벽을 삽입해야 합니다.f새로운 가치의 실현을 위해x값이 변경되기 전 또는 그 이전에 다른 프로세서에 표시됩니다.f또 다른 중요한 점은 스레드 #1이 액세스하기 전에 메모리 장벽도 삽입해야 한다는 것입니다.x가치를 보증하다x값의 변화를 확인하기 전에는 판독되지 않습니다.f.

또 다른 예는 드라이버가 다음 시퀀스를 실행하는 경우입니다.

 준비한다. 데이터. 위해서 a 하드웨어 모듈  // 메모리 펜스가 필요합니다.  트리거  하드웨어 모듈 로. 과정  데이터. 

프로세서의 스토어 조작이 순서대로 실행되지 않으면 메모리 내의 데이터가 준비되기 전에 하드웨어 모듈이 트리거될 수 있습니다.

다른 예시(실제로 발생하는 사소한 것이 아님)에 대해서는 이중 체크된 잠금을 참조하십시오.

멀티스레드 프로그래밍 및 메모리 가시성

멀티스레드 프로그램에서는 보통 Java 및 같은 고급 프로그래밍 환경에서 제공되는 동기화 프리미티브를 사용합니다.NET Framework 또는 POSIX 스레드나 Windows API 등의 Application Programming Interface(API; 응용 프로그램프로그래밍 인터페이스)입니다.병렬 실행 스레드에서 리소스에 대한 액세스를 동기화하기 위해 뮤텍스 및 세마포어와 같은 동기화 프리미티브가 제공됩니다.이러한 프리미티브는 일반적으로 예상되는 메모리 가시성 시멘틱스를 제공하기 위해 필요한 메모리 장벽과 함께 구현됩니다.이러한 환경에서는 일반적으로 메모리 장벽을 명시적으로 사용할 필요가 없습니다.

각 API 또는 프로그래밍 환경은 원칙적으로 메모리 가시성 시멘틱스를 정의하는 자체 높은 수준의 메모리 모델을 가지고 있습니다.프로그래머는 일반적으로 이러한 높은 수준의 환경에서 메모리 장벽을 사용할 필요가 없지만 가능한 한 메모리 가시성의 의미를 이해하는 것이 중요합니다.메모리 가시성 시멘틱스가 항상 일관되게 지정되거나 문서화되는 것은 아니기 때문에 이러한 이해가 반드시 쉬운 것은 아닙니다.

프로그래밍 언어 의미론이 기계어 연산 코드와 다른 추상화 수준에서 정의되는 것처럼 프로그래밍 환경의 메모리 모델은 하드웨어 메모리 모델과는 다른 추상화 수준에서 정의된다.이 차이를 이해하고 특정 프로그래밍 환경의 저수준 하드웨어 메모리 장벽 시멘틱스와 고수준 메모리 가시성 시멘틱스 사이에 항상 단순한 매핑이 존재하는 것은 아님을 깨닫는 것이 중요합니다.그 결과, 특정 플랫폼의 POSIX 스레드 실장에서는 사양에서 요구하는 것보다 더 강력한 장벽이 적용될 수 있습니다.지정이 아닌 구현된 메모리 가시성을 활용하는 프로그램은 이식할 수 없을 수 있습니다.

대 컴파일러가 저장되어 있는 순서 최적화Out-of-order을 집행한다

하드웨어 수준에서만 메모리 배리어 지침 주소가 저장되어 있는 순서 효과.컴파일러는 또 프로그램 최적화 프로세스의 일환으로 지침을 선택할 수 있다.비록 평행 프로그램 거동에 관한 영향은 두 경우와 유사할 수 있지만 일반적으로 그것은 별도 조치 실행의 여러 스레드 별로 상호 공유될 수 있게 데이터에 대한 컴파일러가 저장되어 있는 순서 최적화를 금지하는 필요하다.

C와 C++에서,. 휘발성 키워드 C와 C++프로그램을 직접적으로 액세스 하memory-mapped/O을 허용하기 위한 것이었다.메모리 맵 입출력 일반적으로 그 읽기와 쓴다 소스 코드에 지정된 정확한 순서가 없누락하여 지정된에서 일어나야 한다.읽기의 컴파일러에 의해 누락 또는 reorderings고 쓰는 프로그램과 장치 메모리 매핑 된 입출력을 통해 액세스 하는 사이의 통신을 깨곤 했다.AC또는 C++컴파일러도 없으며, 같은 휘발성 위치(가변)에 다른 그러한 행동에 상대 read/writes을 선택할 수 있고 휘발성 메모리 위치에 쓰기를 생략하지 않을 수 있다.그 키워드 volatiledoes 기억 장애물 cache-consistency을 시행하는 것을 보장하지.따라서, 휘발성 혼자의 사용이 모든 시스템과 CPU로inter-thread 의사 소통을 위해 변수를 이용하기에 부족하다.[1]

그 C와 C++표준 이전 C11과 C++11에(또는 다중 프로세서)[2]과 같은, 휘발성의 유용성은 컴파일러와 하드웨어에 달려 있는 여러 스레드를 해결하지 않다.비록 휘발성 보장은 변동이 심한 읽기와 취약한 회한 정확한 순서는 소스 코드에 지정된에서 일어날 것이라고는 컴파일러 코드를 생성할 수 있(또는 CPU실행 re-order 수 있)를 휘발성 읽기 또는 쓰기는 reordered로 여기다에 비휘발성 읽기 또는 회한, 따라서 제한이 그 유용성으로inter-thread 깃발이나.뮤텍스는 이렇게 차단하는 컴파일러지만 일부 컴파일러에서는 gcc처럼 인라인 어셈블리 코드를 둘러보고"기억"휘발성 태그를 부착한, asm 휘발성("":::"기억"): 같은;(메모리 주문에)Compile-time 메모리 주문하고 더 많은 예제를 참조하십시오)작전을 선택하지 않을 것이다 특정하다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ "Volatile Considered Harmful". Kernel.org.
  2. ^ Boehm, Hans (June 2005). Threads cannot be implemented as a library. Proceedings of the 2005 ACM SIGPLAN conference on Programming language design and implementation. Association for Computing Machinery. CiteSeerX 10.1.1.308.5939. doi:10.1145/1065010.1065042.

외부 링크