缓存是由高速缓存硬件透明地控制到处理器上的,所以如果我们在C程序中使用易失性变量,如何保证我的程序每次从指定的实际内存地址读取数据,而不是缓存。
我的理解是,
因此,如果我需要每次都必须读取内存地址,那么如何确保它不是从缓存引用的,而是来自所需的地址?
有些怎么说,这两个概念并不能很好地结合在一起。请澄清它是如何做到的。
(想象一下我们在缓存中有回写策略(如果需要分析问题))
谢谢你,微内核:)
发布于 2011-10-24 15:27:42
固件开发人员在这里。这是嵌入式编程中的一个标准问题,也是许多(甚至是非常有经验的)开发人员遇到的问题。
我的假设是,您正在尝试访问硬件寄存器,并且寄存器值会随着时间的推移而改变(无论是中断状态、计时器、GPIO指示等等)。
volatile关键字只是解决方案的一部分,在许多情况下可能没有必要。这会导致每次使用变量时都会从内存中重新读取变量(而不是由编译器优化,或者通过多个用途存储在处理器寄存器中),但是“正在读取的内存”是实际的硬件寄存器还是缓存的位置,您的代码不知道,并且不受volatile关键字的影响。如果您的函数只读取寄存器一次,那么您可能可以关闭volatile,但作为一般规则,我建议大多数硬件寄存器应该定义为volatile。
更大的问题是缓存和缓存一致性。这里最简单的方法是确保您的寄存器位于未缓存的地址空间中。这意味着每次访问寄存器时,都保证读取/写入实际的硬件寄存器,而不是缓存内存。一种更复杂但可能更好的方法是使用缓存的地址空间,并让您的代码手动强制对特定情况进行缓存更新。对于这两种方法来说,这是如何实现的,是依赖于体系结构的,超出了问题的范围。它可能涉及MTRRs (用于x86)、MMU、页表修改等。
希望这能有所帮助。如果我错过了什么,让我知道,我会扩大我的答案。
发布于 2011-10-24 07:26:58
从你的问题上看,你有一种误解。
正如您所描述的,Volatile关键字与缓存无关。
当为变量指定关键字volatile时,它会提示编译器不要执行某些优化,因为该变量可能会意外地从程序的其他部分更改。
这里的意思是编译器不应该重用已加载在寄存器中的值,而是再次访问内存,因为寄存器中的值不能保证与存储在内存中的值相同。
与缓存内存有关的其他内容与程序员没有直接关系。
我的意思是CPU的任何高速缓存内存与RAM的同步是一个完全不同的主题。
发布于 2011-10-24 06:59:48
我的建议是将页面标记为虚拟内存管理器未缓存的页面。
在Windows中,这是通过调用PAGE_NOCACHE时设置VirtualProtect来完成的。
出于某种不同的目的,SSE 2指令有防止缓存污染的_mm_stream_xyz指令,尽管我认为它们不适用于这里的情况。
在任何一种情况下,在C中都没有可移植的方式来实现您想要的;您必须使用OS功能。
https://stackoverflow.com/questions/7872175
复制相似问题