-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory_model.html
201 lines (174 loc) · 8.1 KB
/
memory_model.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Memory Model</title>
<link rel="stylesheet" type="text/css" href="/htmlize.css"/>
<link rel="stylesheet" type="text/css" href="./htmlize.css"/>
<link rel="stylesheet" type="text/css" href="../htmlize.css"/>
<link rel="stylesheet" type="text/css" href="../../htmlize.css"/>
<link rel="stylesheet" type="text/css" href="/readtheorg.css"/>
<link rel="stylesheet" type="text/css" href="./readtheorg.css"/>
<link rel="stylesheet" type="text/css" href="../readtheorg.css"/>
<link rel="stylesheet" type="text/css" href="../../readtheorg.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://fniessen.github.io/org-html-themes/src/lib/js/jquery.stickytableheaders.min.js"></script>
<script type="text/javascript" src="https://fniessen.github.io/org-html-themes/src/readtheorg_theme/js/readtheorg.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
<link rel="stylesheet" type="text/css" href="/main.css" media="screen" />
<link rel="stylesheet" type="text/css" href="../main.css" media="screen" />
<link rel="stylesheet" type="text/css" href="../../main.css" media="screen" />
<link rel="stylesheet" type="text/css" href="./main.css" media="screen" />
<link rel = "icon" href = "/icon.png" type = "image/x-icon">
</head>
<body>
<div id="content" class="content">
<h1 class="title">Memory Model</h1>
<div id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org000000f">1. Memory Model</a>
<ul>
<li><a href="#ID-ff35b663-fd3f-4ffb-9273-b2dfe4c741b8">1.1. barrier</a>
<ul>
<li><a href="#org0000000">1.1.1. acquire barrier</a></li>
<li><a href="#org0000003">1.1.2. release barrier</a></li>
<li><a href="#org0000006">1.1.3. example</a></li>
</ul>
</li>
<li><a href="#org000000c">1.2. RISC-V memory model</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-org000000f" class="outline-2">
<h2 id="org000000f"><span class="section-number-2">1.</span> Memory Model</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-ID-ff35b663-fd3f-4ffb-9273-b2dfe4c741b8" class="outline-3">
<h3 id="ID-ff35b663-fd3f-4ffb-9273-b2dfe4c741b8"><span class="section-number-3">1.1.</span> barrier</h3>
<div class="outline-text-3" id="text-1-1">
<p>
<a href="https://mariadb.org/wp-content/uploads/2017/11/2017-11-Memory-barriers.pdf">https://mariadb.org/wp-content/uploads/2017/11/2017-11-Memory-barriers.pdf</a>
</p>
<p>
<a href="https://www.kernel.org/doc/Documentation/memory-barriers.txt">https://www.kernel.org/doc/Documentation/memory-barriers.txt</a>
</p>
<p>
出于性能考虑, cpu/cache 等可以对内存访问进行各种优化, 例如 reorder, defer, combine 等,
通过 barrier 可以对这些优化进行限制, 以避免产生错误的程序, 例如:
</p>
<div class="org-src-container">
<pre class="src src-C">1 <span class="org-comment-delimiter">/* </span><span class="org-comment">thread1</span><span class="org-comment-delimiter"> */</span>
2 result = 2;
3 atomic ready = 1;
4 <span class="org-comment-delimiter">// </span><span class="org-comment">thread 2</span>
5 <span class="org-keyword">while</span> (ready != 1)
6 ;
7 assert(result == 2);
</pre>
</div>
<p>
上述代码可能会 abort, 因为 2/3 可能 reorder, 5/7 可能 reorder.
</p>
<p>
所谓的 reorder, 并非是两个指令通过乱序执行交换了顺序. 因为 ROB (reorder buffer)
会保证指令的 commit (例如内存的写回) 时按程序的顺序执行. 但 cpu 的`内存写回`和
`内存对其它 core 可见`并非一回事. 这里的 `reorder` 主要是指 memory model (cache,
memory controller, …) 导致的 reorder, 例如 cache 导致数据没有写回, 或者 memory
controller (例如 AXI memory controller) 导致的 reorder
</p>
<p>
为了保证上面的结果正确, 需要保证:
</p>
<ol class="org-ol">
<li>5/7 不能 reorder</li>
<li>2/3 不能 reorder</li>
</ol>
<p>
前者通过 acquire barrier 保证, 后者通过 release barrier 保证.
</p>
</div>
<div id="outline-container-org0000000" class="outline-4">
<h4 id="org0000000"><span class="section-number-4">1.1.1.</span> acquire barrier</h4>
<div class="outline-text-4" id="text-1-1-1">
<p>
acquire barrier (read barrier) 表示 barrier 前后的 read 操作不能交换位置.
</p>
<p>
riscv 中带 `aq` 后缀的原子指令 (amo/lr) 相当于一个 acquire barrier, aq 自身与 aq
之后的指令保持`顺序`不变, 即 `lr.aq; lw` 相当于 `lr; acquire_barrier; lw`
</p>
</div>
</div>
<div id="outline-container-org0000003" class="outline-4">
<h4 id="org0000003"><span class="section-number-4">1.1.2.</span> release barrier</h4>
<div class="outline-text-4" id="text-1-1-2">
<p>
riscv 中带 `rl` 后缀的原子指令 (amo/sc) 相当于一个 release barrier, rl 自身与 rl
之前的指令保持`顺序`不变, 即 `sc.rl; sw` 相当于 `sc; release_barrier; sw`
</p>
</div>
</div>
<div id="outline-container-org0000006" class="outline-4">
<h4 id="org0000006"><span class="section-number-4">1.1.3.</span> example</h4>
<div class="outline-text-4" id="text-1-1-3">
<p>
通过 aquire/release barrier, 可以解决前面提到的代码中的问题:
</p>
<div class="org-src-container">
<pre class="src src-C"><span class="org-comment-delimiter">// </span><span class="org-comment">thread 1</span>
result = 2;
<span class="org-function-name">__release_barrier__</span>();
<span class="org-type">atomic</span> <span class="org-variable-name">ready</span> = 1;
<span class="org-comment-delimiter">// </span><span class="org-comment">thread 2</span>
<span class="org-keyword">while</span> (ready != 1) <span class="org-function-name">__acquire_barrier__</span>();
<span class="org-function-name">assert</span>(result == 2);
</pre>
</div>
</div>
</div>
<div id="outline-container-org0000009" class="outline-4 references">
<h4 id="org0000009">Backlinks</h4>
<div class="outline-text-4" id="text-org0000009">
<p>
<a href="aarch64_tutorial.html#ID-1e9be44b-1147-4b34-bfa0-a606ae516fa0">AArch64 Tutorial</a>
(<i>AArch64 Tutorial > AArch64 Assembly > instructions > Misc > LDXR/STXR/LDAXR/STLXR</i>): LDAXR 类似于 RISC-V 的 lr.aq, STLXR 类似于 RISC-V 的 sc.rl, 即包含隐式的 <a href="#ID-ff35b663-fd3f-4ffb-9273-b2dfe4c741b8">barrier</a> 语义
</p>
<p>
<a href="riscv/riscv_tutorial.html#ID-69861e6c-ed76-4e86-ab9d-24f98e5334f4">CAS</a>
(<i>RISC-V Tutorial > Standard Extention > RV32A > CAS</i>): 另外, AMO 和 LR/SC 都支持额外的 ordering 信息 (aq/rl), 可以做为 <a href="#ID-ff35b663-fd3f-4ffb-9273-b2dfe4c741b8">barrier</a> 使用
</p>
</div>
</div>
</div>
<div id="outline-container-org000000c" class="outline-3">
<h3 id="org000000c"><span class="section-number-3">1.2.</span> RISC-V memory model</h3>
<div class="outline-text-3" id="text-1-2">
<p>
<a href="https://riscv.org/wp-content/uploads/2018/05/14.25-15.00-RISCVMemoryModelTutorial.pdf">https://riscv.org/wp-content/uploads/2018/05/14.25-15.00-RISCVMemoryModelTutorial.pdf</a>
</p>
<p>
RVWMO 定义了一种宽松的 memory model, 性能会更好, 同时要求代码中使用 aq/rl 进行更精细的控制.
</p>
<p>
RVTSO 比 RVWMO 严格一些, 同时性能也会差一些, 例如所有的 load 隐含着 aq, 所有的
store 隐含着 rl 等. RVTSO 主要是为了与 x86 兼容.
</p>
</div>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: <a href="mailto:[email protected]">[email protected]</a><br />
Date: 2023-07-24 Mon 17:06<br />
Last updated: 2024-02-01 Thu 14:04</p>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="知识共享许可协议" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a>
</div>
</body>
</html>