易失性和缓存行为

时间:2013-09-09 09:21:09

标签: c linux multithreading volatile memorycache

我看了帖子  C volatile variables and Cache Memory

但我很困惑。

问题:
      操作系统是否会自行处理或
 程序员必须以这样的方式编写程序,即变量不应该像缓存一样提到缓存中,就像将变量声明为_Uncached一样。

问候
学习者

2 个答案:

答案 0 :(得分:12)

澄清:

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

可能导致混淆的是CPU缓存与软件缓存(寄存器中的a.k.a变量)。

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 } ,这显然不是您想要的行为。另一个线程。因此,为了防止这种情况,请将其标记为易失性:

{{1}}

希望这会让它更清晰一点。

答案 1 :(得分:1)

I read this wiki page volatile, it gives an example about how gcc optimize the non-volatile variables and how 'volatile' prevent gcc optimizing.
I noticed that after using 'volatile' to qualify the variables, gcc indeed not optimize away the 'volatile' variables, but everytime read/write operation, the generated instructions are using 'movl' to access. I mean, when 'movl' instruction emits a data address, how does the kernel or cpu or other parts judge whether to read it from cache or memory?
Sergey L. has mentioned that the following keypoints:

Your compiler may decide though to "cache" frequent use variables in registers which can then go out of sync with memory because the hardware is unaware of those. This is what the volatile keyword prevents.

As mentioned by Sergey L., now my understanding is 'volatile' only prevents compiler optimization relevant to 'software cache', i.e. put frequent using variables into registers rather than cpu cache, and 'volatile' cannot guarantee the visibility between different threads?
I am still really confused, maybe I still misunderstand that.