易失性和caching行为

我读过post
C volatilevariables和Cache Memory

但是我很困惑。

题:
操作系统是否会照顾自己
程序员必须以这样的方式编写程序:variables不应该像提到variables一样被放入caching中,如_Uncached。

问候
学习者

Solutions Collecting From Web of "易失性和caching行为"

澄清:

volatile是一个C的概念,它告诉编译器每次从内存中获取变量,而不是在寄存器中使用“编译器生成的”缓存版本,或者优化某些代码。

这里可能会引起混淆的是CPU缓存与软件缓存(也就是寄存器中的变量)。

CPU /硬件高速缓存对于程序是100%透明的,并且硬件确保它是100%同步的。 在这里没有什么值得担心的,当你从内存发出一个load ,数据来自CPU缓存,那么它就是在寻址内存中的数据。

你的编译器可能会决定在寄存器中“缓存”经常使用的变量,然后这些变量可能会与内存不同步,因为硬件不知道这些变量。 这是volatile关键字所能防止的。 常见示例:

 int * lock; while (*lock) { // do work // lock mot modified or accessed here } 

优化编译器会看到你没有在循环中使用lock ,并将其转换为:

 if (*lock) while (true) { // do work } 

这显然不是你想要的行为,如果lock是由另一个线程修改。 所以你把它标记为易变的以防止这个:

 volatile int * lock; while (*lock) { // do work } 

希望这个更清楚一点。

我读了这个wiki页面volatile ,它举例说明了gcc如何优化非易失性变量以及“volatile”如何防止gcc优化。
我注意到在使用'volatile'来限定变量之后,gcc确实不会优化'volatile'变量,但是每次读/写操作,生成的指令都使用'movl'来访问。 我的意思是,当'movl'指令发出一个数据地址时,内核或者CPU或者其他部分如何判断是否从缓存或者内存中读取?
谢尔盖·L提到了以下关键点:

你的编译器可能会决定在寄存器中“缓存”经常使用的变量,然后这些变量可能会与内存不同步,因为硬件不知道这些变量。 这是volatile关键字所能防止的。

正如Sergey L.所提到的,现在我的理解是“volatile”,只能防止与“软件缓存”相关的编译器优化,即将频繁使用变量放入寄存器而不是cpu缓存中,而“volatile”不能保证不同线程之间的可见性。
我仍然很困惑,也许我仍然误解了这一点。