在
libuv source,我发现这个代码:
/* 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;
有人可以解释一下吗?
什么是高速缓存行?
另外,我猜一个条件存储是一些Assembler指令,检查一些东西,如果成功,写一些值.对?
这样的结构何时有意义?我猜并不总是,因为否则编译器只会总是使用条件存储,对吧?
解决方法
高速缓存由快速存储器组成,由于历史原因,被称为行.当写入高速缓存行时,它被标记为“脏”,这意味着在缓存控制器硬件中设置一个位,表示该行需要被复制到其他级别的缓存和/或主存储器系统可以访问它.
一般来说,存储器层级的每个级别:寄存器,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,0 no_store: ... code continues
如果if语句丢失,那么只有最后一个mov指令.
NB评论者指出,在重要的处理器架构上存在单一的“条件移动/存储”指令.我没有看到gcc生产一个.
这是否值得优化是非常有争议的.条件有自己的冲洗指令管道的风险(另一种冲洗).不要在没有明确证据证明需要的情况下为了速度而牺牲清晰度.