高速缓存以快速内存块的形式组织,由于历史原因,这些块被称为行。当您写入缓存行时,它被标记为“脏”,这意味着在缓存控制器硬件中设置了一个位,表示该行需要在其他部分之前复制到其他级别的缓存和/或主内存系统可以访问它。
通常,内存层次结构的每一级:寄存器、L1、L2、L3 ... 高速缓存、主内存和交换空间都具有相同信息的不同副本。确保系统的不同部分(处理器、DMA、视频子系统等)看到相同的值,即使一个或多个副本可能已更改,这称为一致性问题。
一般的解决方案是暂停以将更新的值复制到层次结构的不同级别。这称为冲洗。
刷新可能会花费 10 到 - 在最坏的情况下会导致页面错误 - 可能是数百万个处理器周期。
由于成本高昂,硬件设计人员不遗余力地尽量减少对冲洗的需求。在这里,程序员也承担了责任。
评论是说“如果缓存已经在标志中包含一个零,我们不要在零上写一个零,因为这会将缓存行标记为脏,这可能会导致不必要的刷新。”
“条件存储”是一个有点晦涩的术语。它只是指在正常存储周围的零跳转,这是编译器将从if
语句中生成的代码。在 X86 中,它看起来像:
;; assume edi holds value of pointer 'loop'
;; and flag is a constant offset for the 'stop_flag' field.
cmp dword ptr [edi, flag], 0
jz no_store
mov [edi, flag], 0
no_store:
... code continues
如果缺少 if 语句,您将只有最后一条mov
指令。
NB一位评论者指出,在重要的处理器架构上确实存在单一的“条件移动/存储”指令。我还没有看到gcc
生产一个。
这是否值得优化是非常值得商榷的。条件语句有自己的刷新指令流水线的风险(一种不同的刷新)。永远不要在没有明确证据表明需要的情况下牺牲清晰度来换取速度。