29 메모리 모델 (Memory Model)

메모리 일관성 모델 또는 memory model 은 SharedArrayBuffer 로 백업된 TypedArray 인스턴스 접근과 Atomics 객체의 메서드를 통해 발생하는 Shared Data Block 이벤트의 가능한 순서를 지정한다. 프로그램에 (아래 정의된) 데이터 레이스가 없을 때 이벤트들의 순서는 각 에이전트의 동작을 인터리빙한 것과 같이 순차적 일관성(sequentially consistent)으로 보인다. 프로그램에 데이터 레이스가 있을 때 공유 메모리 연산은 순차적 비일관성처럼 보일 수 있다. 예를 들어, 프로그램은 인과성 위반 동작 및 그 밖의 놀라운 현상을 보일 수 있다. 이러한 놀라움은 컴파일러 변환과 CPU 설계(예: 순서 재배치 실행 및 추측 실행)에서 비롯된다. 메모리 모델은 프로그램이 순차적 일관성 동작을 보이는 정확한 조건과 데이터 레이스에서 읽힐 수 있는 가능한 값들을 모두 정의한다. 즉, 정의되지 않은 동작은 없다.

메모리 모델은 SharedArrayBuffer 의 추상 연산 또는 평가 중 Atomics 객체 메서드에 의해 도입된 이벤트에 대한 관계 제약으로 정의된다.

Note

이 절은 SharedArrayBuffer 추상 연산이 도입하는 이벤트에 대한 공리적(axiomatic) 모델을 제공한다. 모델은 명세의 나머지와 달리 알고리즘적으로 표현될 수 없음을 강조해야 한다. 추상 연산에 의한 비결정적 이벤트 도입은 ECMAScript 평가의 실행 의미와 메모리 모델의 공리적 의미 사이의 인터페이스이다. 이러한 이벤트의 의미는 평가 내 모든 이벤트의 그래프를 고려하여 정의된다. 이것들은 정적 의미(Static Semantics)나 런타임 의미(Runtime Semantics)가 아니다. 입증된 알고리즘 구현이 아니라 특정 이벤트 그래프가 허용되는지 금지되는지를 결정하는 제약 집합이다.

29.1 메모리 모델 기초 (Memory Model Fundamentals)

공유 메모리 접근(읽기/쓰기)은 아래에서 정의되는 두 그룹, atomic 접근과 data 접근으로 나뉜다. Atomic 접근은 순차적 일관성을 가지며, 즉 에이전트 클러스터의 모든 에이전트가 동의하는 엄격한 전체 순서가 있다. 비-atomic 접근은 모든 에이전트가 동의하는 엄격한 전체 순서가 없으므로 정렬되지(unordered) 않는다.

Note 1

순차적 일관성과 unordered 보다 약하거나 강한(예: release-acquire) 순서는 지원되지 않는다.

Shared Data Block eventReadSharedMemory, WriteSharedMemory 또는 ReadModifyWriteSharedMemory Record 이다.

Table 94: ReadSharedMemory 이벤트 필드 (ReadSharedMemory Event Fields)
Field Name Value Meaning
[[Order]] seq-cst 또는 unordered 이벤트에 대해 메모리 모델이 보장하는 가장 약한 순서.
[[NoTear]] Boolean 이 이벤트가 동일 범위를 가진 여러 write 이벤트로부터 읽을 수 있는지 여부.
[[Block]] Shared Data Block 이벤트가 동작하는 블록.
[[ByteIndex]] 음이 아닌 정수 [[Block]] 내 읽기의 바이트 주소.
[[ElementSize]] 음이 아닌 정수 읽기의 크기.
Table 95: WriteSharedMemory 이벤트 필드 (WriteSharedMemory Event Fields)
Field Name Value Meaning
[[Order]] seq-cst, unordered, 또는 init 이벤트에 대해 메모리 모델이 보장하는 가장 약한 순서.
[[NoTear]] Boolean 이 이벤트가 동일 범위를 가진 여러 read 이벤트로부터 읽힐 수 있는지 여부.
[[Block]] Shared Data Block 이벤트가 동작하는 블록.
[[ByteIndex]] 음이 아닌 정수 [[Block]] 내 쓰기의 바이트 주소.
[[ElementSize]] 음이 아닌 정수 쓰기의 크기.
[[Payload]] 바이트 값 List 다른 이벤트가 읽을 바이트 값 List.
Table 96: ReadModifyWriteSharedMemory 이벤트 필드 (ReadModifyWriteSharedMemory Event Fields)
Field Name Value Meaning
[[Order]] seq-cst Read-modify-write 이벤트는 항상 순차적 일관성.
[[NoTear]] true Read-modify-write 이벤트는 tear 될 수 없다.
[[Block]] Shared Data Block 이벤트가 동작하는 블록.
[[ByteIndex]] 음이 아닌 정수 [[Block]] 내 read-modify-write 의 바이트 주소.
[[ElementSize]] 음이 아닌 정수 read-modify-write 의 크기.
[[Payload]] 바이트 값 List [[ModifyOp]] 에 전달될 바이트 값 List.
[[ModifyOp]] read-modify-write 수정 함수 읽은 바이트 List[[Payload]] 로부터 수정된 바이트 List 를 반환하는 추상 클로저.

이러한 이벤트는 추상 연산 또는 Atomics 객체 메서드에 의해 도입된다.

일부 연산은 Synchronize 이벤트도 도입할 수 있다. Synchronize event 는 필드가 없으며, 다른 이벤트의 허용 순서를 직접 제한하기 위해 존재한다.

Shared Data Block 및 Synchronize 이벤트 외에 호스트 특화 이벤트가 있다.

ReadSharedMemory, WriteSharedMemory, ReadModifyWriteSharedMemory 이벤트의 범위(range)는 [[ByteIndex]] 부터 [[ByteIndex]] + [[ElementSize]] - 1 까지의 연속 정수 집합이다. 두 이벤트의 [[Block]] 이 같고 범위가 원소별 동일하면 범위가 같다. [[Block]] 이 같고 범위가 동일하지 않으며 교집합이 비어 있지 않으면 범위가 겹친다(overlapping). [[Block]] 이 다르거나 범위가 같지도 겹치지도 않으면 범위는 분리(disjoint)되었다.

Note 2

계정해야 할 호스트 특화 동기화 이벤트 예: 한 에이전트에서 다른 에이전트로 SharedArrayBuffer 를 보내기(브라우저의 postMessage), 에이전트 시작/종료, 공유 메모리 외 채널을 통한 에이전트 클러스터 내 통신. 특정 실행 execution 에 대해 이러한 이벤트는 host-synchronizes-with 엄격 부분 순서로 호스트에 의해 제공된다. 추가로, 호스트execution.[[EventList]]호스트 특화 동기화 이벤트를 추가하여 is-agent-order-before 관계에 참여할 수 있다.

이벤트는 아래에 정의된 관계에 의해 후보 실행 내에서 순서화된다.

29.2 에이전트 이벤트 레코드 (Agent Events Records)

Agent Events Record 는 다음 필드를 가진 Record 이다.

Table 97: Agent Events Record 필드 (Agent Events Record Fields)
Field Name Value Meaning
[[AgentSignifier]] 에이전트 식별자 이 순서를 발생시킨 평가의 에이전트.
[[EventList]] 이벤트 List 평가 중 리스트에 이벤트가 추가된다.
[[AgentSynchronizesWith]] Synchronize 이벤트 쌍 List 운영상 의미가 도입한 동기화 관계.

29.3 Chosen Value 레코드 (Chosen Value Records)

Chosen Value Record 는 다음 필드를 가진 Record 이다.

Table 98: Chosen Value Record 필드 (Chosen Value Record Fields)
Field Name Value Meaning
[[Event]] Shared Data Block event 이 선택 값에 대해 도입된 ReadSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트.
[[ChosenValue]] 바이트 값 List 평가 동안 비결정적으로 선택된 바이트.

29.4 후보 실행 (Candidate Executions)

candidate execution 은 에이전트 클러스터 평가의 다음 필드를 가진 Record 이다.

Table 99: Candidate Execution Record 필드 (Candidate Execution Record Fields)
Field Name Value Meaning
[[EventsRecords]] Agent Events Records List 평가 중 추가된 이벤트 List 를 에이전트에 매핑.
[[ChosenValues]] Chosen Value Records List 평가 중 선택된 바이트 값 ListReadSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트에 매핑.

empty candidate execution 은 필드가 빈 List 인 candidate execution Record 이다.

29.5 메모리 모델을 위한 추상 연산 (Abstract Operations for the Memory Model)

29.5.1 EventSet ( execution )

The abstract operation EventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events 를 빈 Set 으로 둔다.
  2. execution.[[EventsRecords]] 의 각 Agent Events Record aer 에 대해,
    1. aer.[[EventList]] 의 각 이벤트 E 에 대해
      1. Eevents 에 추가한다.
  3. events 를 반환한다.

29.5.2 SharedDataBlockEventSet ( execution )

The abstract operation SharedDataBlockEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events 를 빈 Set 으로 둔다.
  2. EventSet(execution) 의 각 이벤트 E 에 대해
    1. EReadSharedMemory, WriteSharedMemory, ReadModifyWriteSharedMemory 이벤트이면 Eevents 에 추가한다.
  3. events 를 반환한다.

29.5.3 HostEventSet ( execution )

The abstract operation HostEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events 를 빈 Set 으로 둔다.
  2. EventSet(execution) 의 각 이벤트 E 에 대해
    1. ESharedDataBlockEventSet(execution) 에 없으면 Eevents 에 추가한다.
  3. events 를 반환한다.

29.5.4 ComposeWriteEventBytes ( execution, byteIndex, Ws )

The abstract operation ComposeWriteEventBytes takes arguments execution (a candidate execution), byteIndex (a non-negative integer), and Ws (a List of either WriteSharedMemory or ReadModifyWriteSharedMemory events) and returns a List of byte values. It performs the following steps when called:

  1. byteLocationbyteIndex 로 둔다.
  2. bytesRead 를 새 빈 List 로 둔다.
  3. Ws 의 각 요소 W 에 대해
    1. Assert: W 는 자신의 범위에 byteLocation 을 포함한다.
    2. payloadIndexbyteLocation - W.[[ByteIndex]] 로 둔다.
    3. WWriteSharedMemory 이벤트이면
      1. byteW.[[Payload]][payloadIndex] 로 둔다.
    4. 아니면
      1. Assert: WReadModifyWriteSharedMemory 이벤트.
      2. bytesValueOfReadEvent(execution, W) 로 둔다.
      3. bytesModifiedW.[[ModifyOp]](bytes, W.[[Payload]]) 로 둔다.
      4. bytebytesModified[payloadIndex] 로 둔다.
    5. bytebytesRead 끝에 추가한다.
    6. byteLocationbyteLocation + 1 로 설정한다.
  4. bytesRead 를 반환한다.
Note 1

read-modify-write 수정 [[ModifyOp]]ReadModifyWriteSharedMemory 이벤트를 도입하는 Atomics 객체의 함수 프로퍼티로 제공된다.

Note 2

이 추상 연산은 write 이벤트 List 를 바이트 값 List 로 합성한다. 이는 ReadSharedMemoryReadModifyWriteSharedMemory 이벤트의 이벤트 의미에서 사용된다.

29.5.5 ValueOfReadEvent ( execution, R )

The abstract operation ValueOfReadEvent takes arguments execution (a candidate execution) and R (a ReadSharedMemory or ReadModifyWriteSharedMemory event) and returns a List of byte values. It performs the following steps when called:

  1. Wsexecution 에서 reads-bytes-from(R) 로 둔다.
  2. Assert: Ws 는 길이가 R.[[ElementSize]] 와 같은 WriteSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트 List 이다.
  3. ComposeWriteEventBytes(execution, R.[[ByteIndex]], Ws) 를 반환한다.

29.6 후보 실행의 관계 (Relations of Candidate Executions)

다음 관계와 수학적 함수는 특정 후보 실행 위에서 매개변수화되며 그 이벤트들을 순서화한다.

29.6.1 is-agent-order-before

후보 실행 execution 에 대해, 그 is-agent-order-before 관계는 다음을 만족하는 최소 관계이다.

  • 이벤트 E, D 에 대해 execution.[[EventsRecords]] 의 어떤 Agent Events Record aer 가 있어 aer.[[EventList]]ED 둘 다 포함되고 EList 순서에서 D 앞에 있으면 E is-agent-order-before D 이다.
Note

각 에이전트는 평가 중 per-agent 엄격 전체 순서로 이벤트를 도입한다. 이것은 그 엄격 전체 순서들의 합집합이다.

29.6.2 reads-bytes-from

후보 실행 execution 에 대해, 그 reads-bytes-from 함수는 SharedDataBlockEventSet(execution) 의 이벤트를 SharedDataBlockEventSet(execution) 내 이벤트 List 로 매핑하는 수학적 함수이며 다음 조건을 만족한다.

후보 실행은 항상 reads-bytes-from 함수를 허용한다.

29.6.3 reads-from

후보 실행 execution 에 대해, 그 reads-from 관계는 다음을 만족하는 최소 관계이다.

29.6.4 host-synchronizes-with

후보 실행 execution 에 대해, 그 host-synchronizes-with 관계는 적어도 다음을 만족하는 호스트 제공 엄격 부분 순서이다.

  • E host-synchronizes-with D 이면 HostEventSet(execution) 이 ED 를 포함한다.
  • host-synchronizes-with 와 is-agent-order-before 의 합집합은 순환이 없다.
Note 1

호스트 특화 이벤트 E, D 에 대해 E host-synchronizes-with D 이면 E happens-before D 이다.

Note 2

이 관계는 HTML 워커 간 postMessage 같은 추가 동기화 메커니즘을 호스트가 제공할 수 있게 한다.

29.6.5 synchronizes-with

후보 실행 execution 에 대해, 그 synchronizes-with 관계는 다음을 만족하는 최소 관계이다.

  • 이벤트 R, W 에 대해 R reads-from W, R.[[Order]]seq-cst, W.[[Order]]seq-cst, 그리고 R, W 범위가 같으면 W synchronizes-with R.
  • execution.[[EventsRecords]] 의 각 eventsRecord 에 대해:
    • eventsRecord.[[AgentSynchronizesWith]] 가 (S, Sw) 를 포함하면 S synchronizes-with Sw.
  • execution.[[HostSynchronizesWith]] 가 (E, D) 를 포함하면 E synchronizes-with D.
Note 1

문헌 관례상 write 이벤트가 read 이벤트와 synchronizes-with 관계를 가진다.

Note 2

init 이벤트는 이 관계에 참여하지 않고 happens-before 에 의해 직접 제약된다.

Note 3

reads-from 로 연결된 모든 seq-cst 이벤트가 synchronizes-with 로 연결되지는 않는다. 범위가 같은 경우에만 그렇다.

Note 4

W synchronizes-with R 라도 RW 이외의 write 로부터 reads-from 할 수 있다.

29.6.6 happens-before

후보 실행 execution 에 대해, 그 happens-before 관계는 다음을 만족하는 최소 관계이다.

  • 이벤트 E, D 에 대해 다음 중 하나가 참이면 E happens-before D:

Note

happens-before 는 agent-order 의 상위 집합이므로 후보 실행은 단일 스레드 평가 의미와 합치된다.

29.7 유효한 실행의 속성 (Properties of Valid Executions)

29.7.1 Valid Chosen Reads

후보 실행 execution 이 아래 알고리즘이 true 를 반환하면 valid chosen reads 를 가진다.

  1. SharedDataBlockEventSet(execution) 의 각 ReadSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트 R 에 대해
    1. chosenValueRecordexecution.[[ChosenValues]][[Event]]R 인 요소로 둔다.
    2. chosenValuechosenValueRecord.[[ChosenValue]] 로 둔다.
    3. readValueValueOfReadEvent(execution, R) 로 둔다.
    4. chosenLenchosenValue 의 원소 수로 둔다.
    5. readLenreadValue 의 원소 수로 둔다.
    6. chosenLenreadLen 이면
      1. false 반환.
    7. 0 이상 chosenLen 미만 정수 i 중 일부에 대해 chosenValue[i] ≠ readValue[i] 이면
      1. false 반환.
  2. true 반환.

29.7.2 Coherent Reads

후보 실행 execution 이 아래 알고리즘이 true 면 coherent reads 를 가진다.

  1. SharedDataBlockEventSet(execution) 의 각 ReadSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트 R 에 대해
    1. Wsreads-bytes-from(R) 로 둔다.
    2. byteLocationR.[[ByteIndex]] 로 둔다.
    3. Ws 의 각 요소 W 에 대해
      1. R happens-before W 이면 false 반환.
      2. byteLocation 을 범위에 가지는 WriteSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트 V 가 존재하고 W happens-before VV happens-before R 이면 false 반환.
      3. byteLocationbyteLocation + 1 로 설정.
  2. true 반환.

29.7.3 Tear Free Reads

후보 실행 execution 이 아래 알고리즘이 true 면 tear free reads 를 가진다.

  1. SharedDataBlockEventSet(execution) 의 각 ReadSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트 R 에 대해
    1. R.[[NoTear]]true 이면
      1. R.[[ByteIndex]] % R.[[ElementSize]] == 0 임을 단언.
      2. R reads-from W 이고 W.[[NoTear]]true 인 각 이벤트 W 에 대해
        1. R, W 범위가 같고 이벤트 V 가 존재하여 V, W 범위가 같고 V.[[NoTear]] true 이며 WV, 그리고 R reads-from V 이면 false 반환.
  2. true 반환.
Note

이벤트의 [[NoTear]]true 는 해당 이벤트가 정수 TypedArray 접근으로 도입되었을 때이고, 부동소수 TypedArray 또는 DataView 접근이면 false 이다.

직관적으로 이는 정렬된(integer TypedArray) 방식으로 메모리 범위를 접근할 때 동일 범위를 가진 여러 write 이벤트와 경쟁 중 한 write 이벤트가 “승리”해야 함을 의미한다. 보다 정확히, 정렬된 read 이벤트는 같은 범위를 가진 서로 다른 여러 write 이벤트들의 바이트를 혼합해 읽을 수 없다. 다만 겹치는 범위를 가진 여러 write 이벤트로부터 읽는 것은 가능하다.

29.7.4 순차적 일관 Atomics (Sequentially Consistent Atomics)

후보 실행 execution 에 대해 is-memory-order-beforeEventSet(execution) 의 모든 이벤트에 대한 엄격 전체 순서이며 다음을 만족한다.

후보 실행이 is-memory-order-before 관계를 허용하면 sequentially consistent atomics 를 가진다.

Note 3

is-memory-order-before 는 EventSet(execution) 의 모든 이벤트를 포함하지만 happens-beforesynchronizes-with 로 제약되지 않은 이벤트는 순서에서 어디든 위치할 수 있다.

29.7.5 유효한 실행 (Valid Executions)

후보 실행 execution 이 아래 모두 참이면 유효 실행(또는 실행)이다.

  • 호스트execution 에 대한 host-synchronizes-with 관계를 제공.
  • execution 이 엄격 부분 순서인 happens-before 관계를 허용.
  • execution 은 valid chosen reads.
  • execution 은 coherent reads.
  • execution 은 tear free reads.
  • execution 은 sequentially consistent atomics.

모든 프로그램은 적어도 하나의 유효 실행을 가진다.

29.8 경쟁 (Races)

실행 executionSharedDataBlockEventSet(execution) 에 포함된 이벤트 E, D 에 대해 아래 알고리즘이 true 를 반환하면 E, Drace 관계이다.

  1. E, D 가 동일 Shared Data Block 이벤트가 아니면
    1. E happens-before DD happens-before E 둘 다가 아닌 경우
      1. E, D 가 모두 WriteSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트이고 범위가 분리되지 않으면
        1. true 반환.
      2. E reads-from D 또는 D reads-from E 이면
        1. true 반환.
  2. false 반환.

29.9 데이터 레이스 (Data Races)

실행 executionSharedDataBlockEventSet(execution) 에 포함된 이벤트 E, D 에 대해 아래 알고리즘이 true 이면 E, Ddata race 관계이다.

  1. E, Drace 이면
    1. E.[[Order]]seq-cst 가 아니거나 D.[[Order]]seq-cst 가 아니면
      1. true 반환.
    2. E, D 범위가 겹치면
      1. true 반환.
  2. false 반환.

29.10 데이터 레이스 자유 (Data Race Freedom)

실행 executionSharedDataBlockEventSet(execution) 내 어떤 두 이벤트도 data race 가 아니면 data race free 이다.

모든 실행이 data race free 이면 프로그램은 data race free 이다.

메모리 모델은 data race free 프로그램에 대해 모든 이벤트의 순차적 일관성을 보장한다.

29.11 공유 메모리 가이드라인 (Shared Memory Guidelines)

Note 1

다음은 공유 메모리를 사용하는 ECMAScript 프로그래머를 위한 지침이다.

프로그램을 data race free 로 유지(즉 동일 메모리 위치에서 동시 비-atomic 연산이 불가능하도록)할 것을 권장한다. Data race free 프로그램은 각 에이전트 평가 의미 단계가 서로 인터리빙되는 의미를 갖는다. 이런 경우 메모리 모델 세부사항을 이해할 필요가 없다.

더 일반적으로, 프로그램이 data race free 가 아니어도 atomic 연산이 어떤 data race 에도 관여하지 않고 경쟁하는 연산이 모두 동일 접근 크기라면 예측 가능한 동작을 가질 수 있다. 가장 단순한 방법은 atomic 과 비-atomic 연산이 다른 메모리 셀을 사용하고 서로 다른 크기의 atomic 접근이 동시에 같은 셀을 접근하지 않게 하는 것이다. 즉 가능한 한 공유 메모리를 강한 타입처럼 다루어야 한다. 경쟁 중 비-atomic 접근의 순서와 타이밍에 의존할 수는 없지만 강한 타입처럼 다루면 값이 “찢어지는(tear)” 일은 없다.

Note 2

다음은 공유 메모리를 사용하는 프로그램에 대한 컴파일러 변환을 작성하는 ECMAScript 구현자를 위한 지침이다.

단일 에이전트 환경에서 유효한 대부분의 프로그램 변환이 다중 에이전트 환경에서도 유효하도록 허용하는 것이 바람직하다. 종종 이러한 변환은 판단이 어렵다. 우리는 메모리 모델이 함축하거나 그보다 강한 규칙 몇 가지를 개략적으로 제시한다.

agent-order slice 를 단일 에이전트에 속하는 is-agent-order-before 부분집합이라 하자.

read 이벤트의 possible read values 는 모든 유효 실행에서 그 이벤트에 대한 ValueOfReadEvent 값들의 집합이다.

공유 메모리가 없을 때 유효한 agent-order slice 변환은 아래 예외를 제외하고 공유 메모리 존재 시에도 유효하다.

  • Atomics 는 고정: 변환은 agent-order slice 의 seq-cst 이벤트를 그 unordered 연산과 재배열하거나 서로 재배열하거나 제거해서는 안 된다.

    (실제로 재배열 금지는 seq-cst 연산이 동기화임을 가정하게 강제한다.)

  • 읽기는 안정적: 주어진 shared memory read 는 한 실행에서 단일 값만 관찰해야 한다.

  • 쓰기는 안정적: 관찰 가능한 모든 shared memory write 는 실행의 프로그램 의미에서 비롯해야 한다.

  • 가능한 읽기 값은 공집합이 아님: 변환은 가능한 읽기 값 집합을 비게 할 수 없다.

여전히 유효한 변환 예: 동일 위치 다수 비-atomic 읽기 병합, 비-atomic 읽기 재배열, 추측 비-atomic 읽기 도입, 동일 위치 다수 비-atomic 쓰기 병합, 서로 다른 위치 비-atomic 쓰기 재배열, 루프 밖으로 비-atomic 읽기 hoist (종료 영향 있어도). 일반적으로 alias 된 TypedArray 는 위치 구분을 어렵게 한다.

Note 3

다음은 공유 메모리 접근에 대한 기계어 코드를 생성하는 ECMAScript 구현자를 위한 지침이다.

ARM 또는 Power 보다 약하지 않은 메모리 모델을 가진 아키텍처에서 비-atomic store/load 는 일반 store/load 로 컴파일할 수 있다. Atomic store/load 는 순차적 일관성을 보장하는 명령으로 컴파일한다. 없으면 메모리 배리어 사용. Read-modify-write 는 아키텍처의 read-modify-write 명령(예: x86 LOCK prefix, ARM load-exclusive/store-exclusive, Power load-link/store-conditional)으로 컴파일.

구체적으로 메모리 모델은 다음과 같은 코드 생성을 허용한다.

  • 프로그램의 모든 atomic 연산은 필요하다고 가정.
  • Atomic 연산은 서로 또는 비-atomic 과 재배열되지 않는다.
  • 함수는 항상 atomic 연산 수행 가능하다고 가정.
  • Atomic 연산은 더 큰 데이터의 read-modify-write 로 구현되지 않는다(플랫폼에 그 크기 atomic 없으면 lock-free 아니게 구현).

단순 코드 생성 패턴:

  • 일반 load/store → 단일 load/store 명령.
  • Lock-free atomic load/store → 전체 펜스, load/store, 전체 펜스.
  • Lock-free atomic RMW → 전체 펜스, atomic RMW 시퀀스, 전체 펜스.
  • Non-lock-free atomic → 스핀락 획득, 전체 펜스, 비-atomic load/store 시리즈, 전체 펜스, 스핀락 해제.

이 매핑은 주소 범위에 대한 atomic 연산이 비-atomic 쓰기나 다른 크기 atomic 과 race 하지 않는 한 올바르다. 메모리 모델은 race 에 관여한 atomic 을 비-atomic 수준으로 강등하여 충분하다. 다만 이 단순 매핑은 atomic 연산을 순차적 일관성 펜스로 사용할 수 있게 하는 등 꽤 강하다.

허용되는 로컬 개선 예:

  • 플랫폼 의존 중복 펜스 제거 (예: x86 에서 load/store 전후 펜스 일부 생략 등).
  • 대부분 플랫폼은 필요한 모든 크기 lock-free atomic 지원.
  • 두 back-to-back 펜스 → 하나로 대체; x86 에서 store 뒤 펜스만 유지 등.