这是之前我在面试的时候遇到的奇怪问题,当时回答的不好,只回答了
“这个是避免编译器帮你省读取,但是不保证多轻量行程的同时存取同步”
要我举例什么时候有用到,我虽然指出有的时候类似poll()或者loop的时候
会用来保护某些用来存hardware读上来的flag,但是现代编译器会很避免这种问题了。
我这些年在linux kernel中是很少看见了,因为io remap的内存位置是non cache的,
非要涉及与cache有关系的,我好像更常用RW barrier。
现在才看到这篇文章,原来在Linux kernel是看不到使用volatile的了
https://lwn.net/Articles/233479/
虽然后来无事入职了,但是我个人对这种很吃编译环境的题目很感冒,觉得什么
年代的问题都会拿出来问(这位面试官还问了类似问题),我又不好给出完全否定的
答案,万一面试官不知道这样的变更怎么办。
我后来查验了Gstreamer的代码,除了那些使用asm或者orc的代码外,好像都没有
看见在用volatile了。应该现代GCC和CLANG都是可以正确应对这部分问题了。
而对于MCU来讲,Keli C或者IAR C这些编译器倒是会根据volatile作出蛮奇怪的
反映的。很多MCU platform上对registers的存取都是通过一个C variable进行的,
有这样的行为倒是一点都不奇怪。而某些使用GCC的可能也会被过度优化,造成
没有进行改有读取作业。文章中有特别注明这里和kernel中的不同:
‘But, within the kernel, I/O memory accesses are always done through
accessor functions; accessing I/O memory directly through pointers
is frowned upon and does not work on all architectures.’
个人倒是不清楚DSP用C compiler会不会有这种问题。