C volatile 变量和高速缓存

标签 c computer-science volatile computer-architecture memorycache

缓存由缓存硬件控制,对处理器透明,所以如果我们在C程序中使用volatile变量,如何保证我的程序每次都从指定的实际内存地址而不是缓存中读取数据。

我的理解是,

  1. Volatile 关键字告诉编译器不应优化变量引用,而应按代码中的编程方式读取。

  2. 缓存由缓存硬件透明控制,因此当处理器发出地址时,它不知道数据是来自缓存还是内存。

因此,如果我需要每次都必须读取内存地址,我如何才能确保它不是从缓存中引用而是从所需地址中引用?

不知为何,这两个概念不能很好地结合在一起。请说明它是如何完成的。

(假设我们在缓存中有回写策略(如果需要分析问题))

谢谢, 微内核:)

最佳答案

这里是固件开发者。这是嵌入式编程中的一个标准问题,也是困扰许多(甚至是非常有经验的)开发人员的问题。

我的假设是您正在尝试访问硬件寄存器,并且该寄存器值会随时间变化(中断状态、计时器、GPIO 指示等)。

volatile 关键字只是解决方案的一部分,在许多情况下可能不是必需的。这会导致变量在每次使用时都从内存中重新读取(而不是被编译器优化或在多次使用时存储在处理器寄存器中),但是是否正在读取的“内存” 是一个实际的硬件寄存器,而缓存位置对于您的代码来说是未知的,并且不受 volatile 关键字的影响。如果您的函数只读取寄存器一次,那么您可以不使用 volatile,但作为一般规则,我建议大多数硬件寄存器应定义为 volatile

更大的问题是缓存和缓存一致性。这里最简单的方法是确保您的寄存器位于未缓存的地址空间中。这意味着每次您访问寄存器时,您都可以保证读取/写入实际的硬件寄存器而不是缓存内存。一种更复杂但性能可能更好的方法是使用缓存地址空间,并让您的代码针对此类特定情况手动强制更新缓存。对于这两种方法,这是如何实现的取决于体系结构并且超出了问题的范围。它可能涉及 MTRR(对于 x86)、MMU、页表修改等。

希望对您有所帮助。如果我遗漏了什么,请告诉我,我会扩展我的答案。

关于C volatile 变量和高速缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7872175/

相关文章:

c - 哪个更适合windows? pthreads 还是 CreateMutex?

algorithm - 动态规划 : Optimal Binary Search Tree

c# - 实现此复合 GetHashCode() 的最佳方法是什么

computer-science - 我如何证明这个 dFa 是最小的?

c - 任何优化都会删除代码(指向数组的 volatile 指针)

作为 cron 运行的 C 脚本给予权限被拒绝错误

c - 来自命令行参数的段错误(核心转储)

java - Volatile是线程安全的那么AtomicInteger需要什么

java - 如果线程 B 希望看到线程 A 所做的更改,是否只能将最后的更改更改为 volatile 变量而不是全部?

c - 冒泡排序程序 C