Created
December 13, 2023 14:43
-
-
Save lesismal/3673322106d032abc10a2a06ee138f9b to your computer and use it in GitHub Desktop.
cpu cache一致性、volatile、编译器优化
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
func main() { | |
flag := true | |
// 协程 A | |
go func() { | |
println("Goroutine start\n") | |
for flag { | |
println("Goroutine flag:", flag) | |
// time.Sleep(time.Second * 1) | |
continue | |
} | |
println("Goroutine finish\n") | |
}() | |
for i := 0; true; i++ { | |
flag = false | |
continue | |
} | |
} |
Author
lesismal
commented
Dec 13, 2023
https://www.v2ex.com/t/999936#reply97
看了下汇编,for 循环里不断设置 flag 的语句这块生成的汇编只有一条 NOPL (空指令)汇编、应该是被编译器优化掉了。
随便在 for 循环里加个 print 之类的,都可以让 flag=false 生效。
OP 的疑问其实是 CPU 指令自己的事情,并不算是编程语言相关的,所以我再提一下这个帖子,建议 OP 先看下:
https://www.51cto.com/article/716546.html
还有例如这个帖子:
https://xiaolincoding.com/os/1_hardware/cpu_mesi.html#mesi-%E5%8D%8F%E8%AE%AE
CPU 多核缓存一致性由 CPU 保证。一些人举例子的 i++是属于多个并发各自执行一组指令时各组指令自己的原子性问题、和 cache 一致性其实应该是无关的。
很多认为的可见性的不一致问题,应该是编译器优化导致的,例如:
#96
c++ const 变量通过指针强改内容但其他用到 const 变量的地方仍然是旧值、因为编译器认为常量直接类似宏替换了,需要 volatile 指定每次读内存主要也是为了告诉编译器不要优化这里的内容
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment