在libuv源代码中,我找到了这段代码:
/* The if statement lets the compiler compile it to a conditional store.
* Avoids dirtying a cache line.
*/
if (loop->stop_flag != 0)
loop->stop_flag = 0;
Run Code Online (Sandbox Code Playgroud)
有人能解释一下吗?
什么是缓存行?
另外,我猜条件存储是一些汇编指令,它检查一些东西,如果成功,写一些值.对?
这种结构什么时候有意义?我想并不总是,因为否则编译器会一直使用条件存储,对吧?
缓存按快速内存块组织,由于历史原因,称为行.当您写入高速缓存行时,它被标记为"脏",这意味着在高速缓存控制器硬件中设置了一个位,表示该行需要在其他部分之前复制到其他级别的高速缓存和/或主存储器.系统可以访问它.
通常,存储器层次结构的每个级别:寄存器,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
Run Code Online (Sandbox Code Playgroud)
如果缺少if语句,则只有最后一条mov指令.
NB一位评论者指出,在重要的处理器架构上确实存在单一的"条件移动/存储"指令.我还没见过第gcc一个.
这是否值得进行优化是非常值得商榷的.条件语具有刷新指令管道的风险(不同类型的刷新).如果没有明确的证据证明需要,就不要牺牲速度的清晰度.