2022-10-03

perfbook 指的是 Is Parallel Programming Hard, And, If So, What Can You Do About It? pdf 版本可以从如下网址获取: https://www.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html


本文不打算从原理上来理解, 仅为了快速使用, 故缺失严谨.


5.4.4

第16行执行一条内存屏障,确保任何看见第17行设置READY状态的CPU,也能看见第9行的效果

awakening-fong 注释:

16  smp_mb();
17 WRITE_ONCE(theft, THEFT_READY);

跨过了16行,就是已经执行过第9行的证据,所以,第17行给出了一个结论。 16行的动作已执行完,清单步骤已查验,17行给个盖章。


内存屏障以成对的形式进行操作。


14.2.4.3 Pair-Wise Memory Barriers

在如下操作中,从外部逻辑分析器的角度来说,CPU 1对A的访问并非绝对早于对B的访问(参见附录C的例子)

CPU 1          CPU 2
access(A);   access(B);
smp_mb();    smp_mb();
access(B);   access(A);

awakening-fong 注释: 这里的外部逻辑分析仪,不可以理解为 其他cpu, cpu之间可以有相关协议,cpu 和 分析仪 之间 却没有这些约定。


但是,如果 CPU 2对B的访问看到CPU 1对B的访问,那么CPU 2对A的访问是确保能够看到CPU 1对A的访问

However, if CPU 2’s access to B sees the result of CPU 1’s access to B, then CPU 2’s access to A is guaranteed to see the result of CPU 1’s access to A.

awakening-fong 注释: 来自 同一个cpu的两变量,这两变量到 其他cpu的传播 受 mb 约束。

C.4.3

CPU 0 executes foo() while CPU 1 executes function bar() in the following code fragment:

1 void foo(void)
2 {
3 a = 1;
4 smp_mb();
5 b = 1;
6 }
7
8 void bar(void)
9 {
10 while (b == 0) continue;
11 assert(a == 1); // 概率导致程序退出
12 }

9.CPU 1执行assert(a==1),并且,由于旧的“a”值还在CPU 1的缓存中,因此陷入错误。

10.虽然陷入错误,CPU 1处理已经排队的“使无效”消息,并且(迟到)在自己的缓存中刷新包含“a”值的缓存行。

awakening-fong 注释:

cpu会试图维护cache line一致性,方法是发送消息,但接收端接收到消息前,可能已经从cache line中读取走旧的值了。

两个变量,其在cpu之间的传播速度不一样,因为传播路径不一样。本例中,b的传播速度快。

C.4.3

1 void foo(void)
2 {
3 a = 1;
4 smp_mb();
5 b = 1;
6 }
7
8 void bar(void)
9 {
10 while (b == 0) continue;
11 smp_mb();
12 assert(a == 1); // 不会让程序退出
13 }

8.CPU 1 现在结束执行while(b==0)continue,因为它发现“b”的值为 1,它处理下一条语句,这是一条内存屏障指令。

9.CPU 1 必须停顿,直到它处理完使无效队列中的所有消息。

10.CPU 1 处理已经入队的“使无效”消息,从它的缓存中使无效包含“a”的缓存行。

11.CPU 1 执行assert(a==1),由于包含“a”的缓存行已经不在它的缓存中,它发送一个“读”消息。

12.CPU 0 以包含新的“a”值的缓存行响应该“读”消息。

13.CPU 1 接收到该缓存行,它包含新的“a”的值1,因此断言不会被触发。

awakening-fong 注释:

写端 cpu0 处理了检查清单 :a写完成,然后 盖章了b置1。
读端 cpu1 看到印章 b,需要刷新认知(配对的mb),重新抓取a。

本文地址: https://awakening-fong.github.io/posts/perf/perfbook-03

转载请注明出处: https://awakening-fong.github.io


若无法评论, 请打开JavaScript, 并通过proxy.


blog comments powered by Disqus