?um/p1-90`메모리 일관성 모델, 또는 메모리 모델은 SharedArrayBuffer를 기반으로 하는
메모리 모델은 평가 중 SharedArrayBuffer의
이 절은 SharedArrayBuffer에 대한
공유 메모리 접근(읽기와 쓰기)은 아래에서 정의되는 두 그룹, atomic 접근과 data 접근으로 나뉜다. Atomic 접근은 순차적으로 일관된다. 즉, agent cluster의 모든 agent가 동의하는 이벤트의 엄격한 전체 순서가 있다. Non-atomic 접근은 모든 agent가 동의하는 엄격한 전체 순서를 가지지 않는다. 즉, unordered이다.
release-acquire와 같이 순차적 일관성보다 약하고 unordered보다 강한 ordering은 지원되지 않는다.
Shared Data Block 이벤트는 ReadSharedMemory, WriteSharedMemory, 또는 ReadModifyWriteSharedMemory
| 필드 이름 | 값 | 의미 |
|---|---|---|
| [[Order]] | 해당 이벤트에 대해 |
|
| [[NoTear]] | Boolean | 이 이벤트와 동일한 |
| [[Block]] | 이벤트가 작동하는 block. | |
| [[ByteIndex]] | 음이 아닌 |
[[Block]] 내 읽기의 바이트 주소. |
| [[ElementSize]] | 음이 아닌 |
읽기의 크기. |
| 필드 이름 | 값 | 의미 |
|---|---|---|
| [[Order]] | 해당 이벤트에 대해 |
|
| [[NoTear]] | Boolean | 이 이벤트와 동일한 |
| [[Block]] | 이벤트가 작동하는 block. | |
| [[ByteIndex]] | 음이 아닌 |
[[Block]] 내 쓰기의 바이트 주소. |
| [[ElementSize]] | 음이 아닌 |
쓰기의 크기. |
| [[Payload]] | 바이트 값의 |
다른 이벤트가 읽을 바이트 값의 |
| 필드 이름 | 값 | 의미 |
|---|---|---|
| [[Order]] | Read-modify- |
|
| [[NoTear]] | Read-modify- |
|
| [[Block]] | 이벤트가 작동하는 block. | |
| [[ByteIndex]] | 음이 아닌 |
[[Block]] 내 read-modify-write의 바이트 주소. |
| [[ElementSize]] | 음이 아닌 |
read-modify-write의 크기. |
| [[Payload]] | 바이트 값의 |
[[ModifyOp]]에 전달될 바이트 값의 |
| [[ModifyOp]] | read-modify-write modification 함수 | 읽은 바이트 값의 |
Shared Data Block 이벤트는
Shared Data Block 이벤트 e의 memory range를 e.[[ByteIndex]](포함)부터 e.[[ByteIndex]] + e.[[ElementSize]](제외)까지의
고려되어야 할 host-specific synchronizing 이벤트의 예는 다음과 같다: 한 agent에서 다른 agent로 SharedArrayBuffer 보내기(예: 브라우저에서 postMessage 사용), agent 시작 및 중지, 공유 메모리 이외의 채널을 통한 agent cluster 내 통신. 특정 실행 execution에 대해, 이러한 이벤트는 host가
이벤트는 아래에 정의된 관계에 의해
Agent Events Record는 다음 필드를 가진
| 필드 이름 | 값 | 의미 |
|---|---|---|
| [[AgentSignifier]] | agent signifier | 이 ordering을 결과로 낳은 평가를 수행한 agent. |
| [[EventList]] | 이벤트는 평가 중 list에 추가된다. | |
| [[AgentSynchronizesWith]] | 조작적 의미론에 의해 도입되는 |
Chosen Value Record는 다음 필드를 가진
| 필드 이름 | 값 | 의미 |
|---|---|---|
| [[Event]] | 이 chosen value를 위해 도입된 |
|
| [[ChosenValue]] | 바이트 값의 |
평가 중 비결정적으로 선택된 바이트. |
agent cluster의 평가에 대한 candidate execution은 다음 필드를 가진
| 필드 이름 | 값 | 의미 |
|---|---|---|
| [[EventsRecords]] | agent를 평가 중 추가된 |
|
| [[ChosenValues]] |
empty candidate execution은 필드가 빈
The abstract operation EventSet takes argument execution (a
The abstract operation SharedDataBlockEventSet takes argument execution (a
The abstract operation HostEventSet takes argument execution (a
The abstract operation ComposeWriteEventBytes takes arguments execution (a
read-modify-write modification [[ModifyOp]]는
이
The abstract operation ValueOfReadEvent takes arguments execution (a
다음 관계와 수학적 함수는 특정
각 agent는 평가 중 agent별 엄격한 전체 순서로 이벤트를 도입한다. 이는 그러한 엄격한 전체 순서들의 합집합이다.
이 postMessage와 같은 추가 synchronization 메커니즘을 제공할 수 있게 한다.
이벤트 eventA와 eventB에 대해, 다음 조건 중 하나라도 참이면 eventA는 execution에서 eventB보다 happens-before이다.
happens-before는 agent-order의 superset이므로,
직관적으로 이 요구 사항은 integer
execution에서 readEvent가 writeEvent로부터
이 절은 같은
이 절은 agent에 대한 forward progress 보장과 함께,
is-memory-order-before는
모든 프로그램은 최소 하나의 valid execution을 가진다.
execution execution과
execution execution과
execution execution은
프로그램은 자신의 모든 execution이 data race free이면 data race free이다.
다음은 공유 메모리로 작업하는 ECMAScript 프로그래머를 위한 지침이다.
프로그램을
더 일반적으로, 프로그램이
다음은 공유 메모리를 사용하는 프로그램에 대해 컴파일러 변환을 작성하는 ECMAScript 구현자를 위한 지침이다.
multi-agent 프로그램에서 각 agent의 성능이 single-agent 설정에서와 마찬가지로 좋도록 보장하기 위해, single-agent 설정에서 유효한 대부분의 프로그램 변환을 multi-agent 설정에서도 허용하는 것이 바람직하다. 이러한 변환은 판단하기 어려운 경우가 많다. 우리는 규범적으로 받아들여지도록 의도된(
agent-order slice를 단일 agent에 관련된
공유 메모리가 없는 경우 유효한 agent-order slice의 모든 변환은 공유 메모리가 있는 경우에도 다음 예외를 제외하고 유효하다.
Atomics are carved in stone: 프로그램 변환은 [[Order]]가
(실제로 reordering 금지는 컴파일러가 모든
Reads must be stable: 주어진 공유 메모리 read는 execution 안에서 단 하나의 값만 관찰해야 한다.
(예를 들어, 프로그램에서 의미상 단일 read인 것이 여러 번 실행되면, 그 후 프로그램은 읽힌 값들 중 하나만 관찰하도록 허용된다. rematerialization으로 알려진 변환은 이 규칙을 위반할 수 있다.)
Writes must be stable: 공유 메모리에 대한 모든 관찰 가능한 write는 execution 안의 프로그램 의미론으로부터 따라야 한다.
(예를 들어, 더 작은 datum을 쓰기 위해 더 큰 위치에 read-modify-write 연산을 사용하거나, 프로그램이 쓸 수 없었던 값을 메모리에 쓰거나, read 이후 다른 agent가 덮어쓸 수 있었던 위치에 방금 읽은 값을 다시 쓰는 것과 같은 특정 관찰 가능한 write를 변환이 도입해서는 안 된다.)
Possible read values must be non-empty: 프로그램 변환은 공유 메모리 read의 possible read values가 비게 만들 수 없다.
(직관에 반하지만, 이 규칙은 사실상 write에 대한 변환을 제한한다. memory model에서 write는
여전히 유효한 변환의 예는 다음과 같다: 같은 위치에서 여러 non-atomic read 병합, non-atomic read reordering, speculative non-atomic read 도입, 같은 위치에 대한 여러 non-atomic write 병합, 서로 다른 위치에 대한 non-atomic write reordering, 그리고 종료에 영향을 미치더라도 loop 밖으로 non-atomic read hoisting. 일반적으로 aliased
다음은 공유 메모리 접근을 위한 machine code를 생성하는 ECMAScript 구현자를 위한 지침이다.
ARM 또는 Power의 LOCK-prefix 명령어, ARM의 load-exclusive/store-exclusive 명령어, Power의 load-link/store-conditional 명령어와 같은 대상 아키텍처의 read-modify-write 명령어로 컴파일될 수 있다.
구체적으로,
Naive code generation은 다음 패턴을 사용한다:
그 매핑은
LOCK-prefix 명령어를 사용하기 때문이다. 많은 플랫폼에는 여러 강도의 fence가 있으며, 순차적 일관성을 깨뜨리지 않고 특정 context에서 더 약한 fence를 사용할 수 있다.