perfbook 03 barrier
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