원문 캡처 · sigarch.org
원문 캡처 · sigarch.org

서로 다른 메모리 모델을 따르는 프로세서나 소프트웨어가 메모리를 공유할 때는 각 모델의 규칙을 함께 적용하는 방법이 필요하다. 유타대학교 컴퓨팅학부의 비제이 나가라잔(Vijay Nagarajan)은 이를 복합 메모리 모델(Compound Memory Model)로 정의하며, 이 규칙이 없으면 실제 시스템에서 오류가 생길 수 있다고 설명한다.

각 구성요소의 모델을 함께 적용한다

엔비디아 Grace Hopper에서는 Arm CPU와 GPU가 하나의 일관된 메모리를 공유하지만, CPU는 Arm 메모리 모델을, GPU는 NVIDIA의 PTX 모델을 따른다. 소프트웨어에서도 사용자 프로그램과 리눅스 커널이 메모리를 직접 공유하며, 커널은 C와 다른 LKMM을 적용한다.

복합 메모리 모델은 전체 시스템에 하나의 모델을 강제로 선택하는 대신, 각 스레드가 자기 구성요소의 메모리 모델을 따르도록 한다. 예를 들어 Arm 스레드는 Arm 규칙을, x86 스레드는 x86-TSO 규칙을 따른다. 메시지 전달에서 Arm 생산자가 릴리스 저장을 하고 x86 소비자가 일반 읽기를 하더라도, 생산자의 쓰기 순서는 Arm의 릴리스가 지키고 소비자의 읽기 순서는 x86-TSO가 지켜 소비자가 새 데이터를 읽게 된다.

이 방식은 각 구성요소의 기존 컴파일러 변환이 독립적으로 올바르게 작동해야 한다는 조건과, Arm 코어가 x86 코어와 함께 있다는 이유만으로 더 강한 모델을 따르도록 설계를 바꾸지 않아도 된다는 조건을 함께 충족한다. 이 개념은 HeteroGen에서 2022년 CPU 모델을 대상으로 처음 형식화됐고, 2023년 Compound Memory Models에서 PTX 같은 GPU 모델까지 확장됐다.

다른 접근법은 시스템 전체에 하나의 모델을 적용한다. HSA 플랫폼 사양은 참여 장치가 HRF 같은 범위 지정 데이터 경합 없는 모델을 따르도록 요구하고, MemGlue는 C11 변형을 시스템 전체의 계약으로 삼자고 제안한다. 나가라잔은 복합 모델은 장치별 모델을 조합하므로 제조업체가 하나의 모델에 합의할 필요가 없고, 각 언어의 기존 컴파일러 변환도 유지할 수 있다고 설명한다.

일관된 연결만으로는 충분하지 않다

CXL 같은 일관성 인터커넥트로 장치를 연결하는 것만으로는 올바른 동작이 보장되지 않는다. 각 장치는 내부 캐시 계층과 자체 일관성 프로토콜을 갖고, 장치별 프로토콜과 인터커넥트를 잇는 연결 로직인 shim이 전체 동작의 정확성에 영향을 준다.

예를 들어 GPU 쪽 shim이 데이터 쓰기에 따른 무효화가 CPU에 도달하기 전에 쓰기 완료를 허용하면, CPU는 갱신된 플래그를 읽고도 자기 캐시에서 오래된 데이터를 읽을 수 있다. 이를 막는 규칙으로 제안된 동기식 전파(Synchronous Propagation)는 장치 안에서 쓰기를 전파할 때 전역으로도 전파하며, 전역 전파가 끝나기 전에는 로컬 전파를 완료하지 않도록 한다. 나가라잔은 검증된 연구에서 이 규칙을 따르는 shim이 CXL 같은 전역 프로토콜 아래에서 기존 무효화 방식과 GPU식 자체 무효화 방식을 조합해도 복합 모델을 보장한다고 밝혔다. 증명은 Lean으로 기계 검증됐다. CXL을 위한 다른 연구로는 shim 설계 규칙을 도출하는 C3와 shim을 자동 합성하는 vCXLGen이 소개됐다.

현존 시스템에서도 모델 간 경계의 문제가 드러난다. 나가라잔 연구팀은 Apple M1에서 Arm 스레드와 TSO 모드 스레드 사이의 메시지 전달을 시험했고, 복합 모델이 금지하는 오래된 데이터를 소비자가 읽는 결과를 관찰했다. Arm 전용 및 TSO 전용 테스트는 올바르게 동작했다. 애플은 TSO 모드가 Arm 스레드와의 동기화에 쓰이도록 설계된 것은 아니라고 확인했다. 반면 Grace Hopper에서는 CPU와 GPU 사이의 메시지 전달 테스트 1,960건에서 Arm/PTX 복합 모델이 허용하는 경우에만 오래된 데이터가 나타났다고 연구팀은 보고했다.

모델을 따로 설계할 때 생기는 문제

Grace Hopper의 C++-Arm 및 C++-PTX 컴파일러 변환은 각각 정확성 증명을 갖췄지만, 순차적 일관성을 보장하는 원자 연산의 구현 방식은 서로 다르다. PTX는 펜스 사이의 전체 순서에 의존하는 반면 Arm은 펜스를 사용하지 않는다. 따라서 GPU에서 시작해 CPU에서 끝나는 동기화 과정에서 C++의 보장이 유지되는지는 두 모델만으로 분명하지 않다.

복합 모델을 형식화하는 과정에서 연구팀은 NVIDIA의 공식 C++-PTX 변환이 건전하지 않다는 점도 발견했다고 나가라잔은 밝혔다. 기계 검증된 증명 자체가 아니라, 기계 검증 범위 밖의 예비 단계에 결함이 있었다. NVIDIA도 이를 확인했다(Beyond the Fence). 연구팀은 다른 모델과 조합되도록 설계한 PTX 모델이 NVIDIA 모델보다 조금 더 강하며, 조합에 필요한 이 추가 강도가 결함도 해결한다고 설명했다. 연구팀의 테스트에서는 NVIDIA GPU가 이미 이 강도를 제공했다.

소프트웨어 경계에서도 문제가 생겼다. C는 프로그래머가 릴리스-어콰이어 쌍이나 순차적 일관성 원자 연산으로 지정한 경우에 메모리 접근 순서를 보장한다. LKMM은 하드웨어가 이미 보존하는 순서도 일부 보장한다. 예를 들어 포인터를 읽은 뒤 역참조하는 두 접근을 LKMM은 순서가 있다고 보지만 C는 그렇지 않다.

리눅스의 kcov 인터페이스에서는 커널이 커버리지 항목을 기록한 뒤 개수를 기록하고, 사용자 코드가 개수를 읽은 뒤 항목을 읽는다. 커널은 두 쓰기 사이에 배리어를 두지 않았고, 사용자 코드는 개수를 완화된 로드로 읽었다. 그 결과 새 개수와 오래된 항목이 함께 보일 수 있었다. 나가라잔은 C와 LKMM 사이의 동작을 명세하는 C/LKMM 복합 모델이 이를 다루며, 양쪽 수정 사항은 리눅스에 반영됐다고 전했다.

나가라잔은 Grace Hopper처럼 Arm과 PTX를 결합한 칩과 사용자 코드·커널 사이의 인터페이스에 복합 모델을 명시적으로 정의해야 한다고 주장한다. 또 메모리 모델을 설계할 때부터 조합 가능성을 기본 원칙으로 삼아야 한다고 덧붙였다. 글은 컴퓨팅 아키텍처 분야에 관한 개인 견해를 담은 기고문이다.