C优化:条件存储,以避免弄脏缓存行

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生产一个.

这是否值得优化是非常有争议的.条件有自己的冲洗指令管道的风险(另一种冲洗).不要在没有明确证据证明需要的情况下为了速度而牺牲清晰度.

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录<future>future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...