Skip to content

Commit f00fac3

Browse files
committed
Update SC.
1 parent 13f5b95 commit f00fac3

File tree

1 file changed

+12
-7
lines changed
  • content/posts/memory-model/sequential-consistency

1 file changed

+12
-7
lines changed

content/posts/memory-model/sequential-consistency/index.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
+++
2-
title = '【内存模型】顺序一致性'
2+
title = '【内存模型】SC'
33
series = '内存模型'
44
date = '2024-05-10'
55
keywords = ['计算机原理', '操作系统', '内存模型', '并发']
@@ -41,6 +41,11 @@ L1: r1 = y;
4141
S2: y = NEW;
4242
L2: r2 = x;
4343
```
44+
说明如下:
45+
- x 和 y 是共享内存中的变量
46+
- 所有 r 是 CPU 本地变量(寄存器)
47+
- L 和 S 代表读(Load)和写(Store)
48+
- x、y 初始值都是 0
4449

4550
另外,我们要约定一些定义和助记符:
4651

@@ -63,7 +68,7 @@ L2: r2 = x;
6368

6469
现在我们可以下结论:
6570
{{< alert "check" >}}
66-
场景一是符合 SC 的,运行结果是`(r1, r2)` == `(0, NEW)`
71+
场景一是符合 SC 的,运行结果是`(r1, r2) == (0, NEW)`
6772
{{< /alert >}}
6873

6974
### 场景二
@@ -72,7 +77,7 @@ L2: r2 = x;
7277
我们可以得出类似的结论:
7378

7479
{{< alert "check" >}}
75-
场景二是符合 SC 的,运行结果是`(r1, r2)` == `(NEW, 0)`
80+
场景二是符合 SC 的,运行结果是`(r1, r2) == (NEW, 0)`
7681
{{< /alert >}}
7782

7883
### 场景三
@@ -81,15 +86,15 @@ L2: r2 = x;
8186
在这个例子中,在单个处理器上连续的指令,在实际执行的时候发生了交错(`S1``L1`之间隔着`S2``S2``L2`之间隔着`L1`),这在现实场景中很常见,但是如果我们对照 SC 的特性,依然可以得到以下结论:
8287

8388
{{< alert "check" >}}
84-
场景三是符合 SC 的,运行结果是`(r1, r2)` == `(NEW, NEW)`
89+
场景三是符合 SC 的,运行结果是`(r1, r2) == (NEW, NEW)`
8590
{{< /alert >}}
8691

8792
### 场景四
8893
最后一个场景的执行如下图:
8994
![](img/sc4.svg "场景4")
9095
这个场景就有点不一样了,因为`S2 <p L2`,但是同时`L2 <m S2`,所以我们可以得出结论:
9196
{{< alert "xmark" >}}
92-
场景四是**不符合 SC** 的,运行结果是`(r1, r2)` == `(0, 0)`
97+
场景四是**不符合 SC** 的,运行结果是`(r1, r2) == (0, 0)`
9398
{{< /alert >}}
9499

95100
## 形式化定义
@@ -102,9 +107,9 @@ L2: r2 = x;
102107
4. 如果 `S(a) <p L(b)`,则 `S(a) <m L(b)``Store -> Load`
103108
- 针对同一内存地址,读(`Load`)总是能得到 `<m` 中最近一次写(`Store`)的值:
104109
```
105-
L(a) = Max<m { S(a) | S(a) <m L(a) }
110+
L(a) = Max<m { S(a) | S(a) <m L(a) }
106111
```
107-
上面公式的意思是,对地址`a``Load`,读到的是在`<m`中最新(Max)的一个对`a`进行`Store`的效果。虽然看起来也像一句废话,但是,在缓存的作用下,这个结果并不是理所当然的。
112+
上面公式的意思是,对地址`a``Load`,读到的是在`<m`中最新(Max)的一个对`a`进行`Store`的效果。
108113

109114
此外,这里除了`Load``Store`,我们要引入第三种读写指令——`RMW``RMW`代表`Read->Modify->Write`,它通常用于这样一种场景:基于内存中某个变量的当前值来更新这个变量,比如把某个变量`++`。通常,做这样的操作,需要三个步骤:
110115
1. 把内存的值读到寄存器中;

0 commit comments

Comments
 (0)