【发布时间】:2013-09-12 18:12:00
【问题描述】:
我看了帖子
C volatile variables and Cache Memory
但我很困惑。
问题:
操作系统是否会自行处理或
程序员必须以这样一种方式编写程序,即变量不应进入缓存,就像将变量声明为 _Uncached 一样。
问候
学习者
【问题讨论】:
标签: c linux multithreading volatile memorycache
我看了帖子
C volatile variables and Cache Memory
但我很困惑。
问题:
操作系统是否会自行处理或
程序员必须以这样一种方式编写程序,即变量不应进入缓存,就像将变量声明为 _Uncached 一样。
问候
学习者
【问题讨论】:
标签: c linux multithreading volatile memorycache
澄清一下:
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 以防止这种情况发生:
volatile int * lock;
while (*lock) {
// do work
}
希望这能让它更清楚一点。
【讨论】:
volatile 应确保告知硬件有关加载和存储的信息。可能需要查阅硬件文档以了解各种配置将如何影响硬件处理其所知道的负载和存储的方式,以及操作系统文档以了解它如何配置硬件,但如果编译器要注册 -在不告诉硬件的情况下缓存变量,所有的赌注都会被取消。