高速缓存以快速内存块的形式组织,由于历史原因,这些块被称为行。当您写入高速缓存行时,它被标记为“脏”,这意味着在高速缓存控制器硬件中设置了一个位,表示该行需要在其他部分之前复制到其他级别的高速缓存和/或主内存系统可以访问它。
一般来说,内存层次结构的每一级:寄存器、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 生产一个。
这是否值得优化值得商榷。条件语句有自己的刷新指令流水线的风险(一种不同的刷新)。永远不要在没有明确证据表明需要的情况下牺牲清晰度来换取速度。