[讨论] volatile在不同环境下的作用

楼主: hizuki (ayaka)   2021-06-17 14:07:49
这是之前我在面试的时候遇到的奇怪问题,当时回答的不好,只回答了
“这个是避免编译器帮你省读取,但是不保证多轻量行程的同时存取同步”
要我举例什么时候有用到,我虽然指出有的时候类似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会不会有这种问题。
作者: TeaEEE (爱不趴 不爱趴)   2021-06-17 17:11:00
volatile用多了效能会很伤吗?
作者: chuegou (chuegou)   2021-06-17 21:14:00
那atomic呢?
作者: Lipraxde (Lipraxde)   2021-06-18 02:30:00
我觉得文章里的 accessor function 指的是 readb / writeb这类也要用 pointer 来读写的,devm_ioremap_resource (ioremap?) 没有去读,应该不算?devm_ioremap_resource 传回来的是 __iomem*,刚刚找了几个地方,在用传回来的 __iomem* 去做读写 (dereference) 的时候,都有透过 readb / writeb 之类的 function/ macro。不太清楚你的观点是?
作者: swhigh (无所事事)   2021-06-26 02:24:00
用到的场景:在MCU里前景程式要检查背景中断更改过的变量值;或是程式码直接读取硬件暂存器值。这时 volatile 好用,其他时候都用不到

Links booklink

Contact Us: admin [ a t ] ucptt.com