Assembly 读然后条件写与写

Assembly 读然后条件写与写,assembly,cpu,low-level,Assembly,Cpu,Low Level,平均来说,哪一个更快?检查值,然后,如果需要,分配,或者简单地分配?或者,用C++术语: bool b; if(b) b = false; 或 假设if()条件为真,概率为50%。答案很可能是高度依赖于架构——请说出您的低级考虑。写入总是会弄脏缓存线-对吗?因此,通过避免写入,我们可以在0.5种情况下避免缓存刷新。但是一个足够智能的缓存可能会检测到一个微不足道的写操作,而不会弄脏自己。但是,无条件写入总是恰好是一个内存操作,而读写平均是1.5个操作 免责声明:这是一个好奇的问题,不是我

平均来说,哪一个更快?检查值,然后,如果需要,分配,或者简单地分配?或者,用C++术语:

bool b;
if(b)
    b = false;

假设if()条件为真,概率为50%。答案很可能是高度依赖于架构——请说出您的低级考虑。写入总是会弄脏缓存线-对吗?因此,通过避免写入,我们可以在0.5种情况下避免缓存刷新。但是一个足够智能的缓存可能会检测到一个微不足道的写操作,而不会弄脏自己。但是,无条件写入总是恰好是一个内存操作,而读写平均是1.5个操作


免责声明:这是一个好奇的问题,不是我实际面临的问题。

在不同的体系结构上对此进行分析以获得实际结果肯定是值得的。

这取决于各种因素:

  • 分支的可预测性(在第一个场景中)
  • b是否已在寄存器中
  • 您正在使用什么体系结构

除了对配置文件的建议外,这实际上还取决于备份写入请求的内存-例如,如果是内存映射闪存设备,写入可能会非常昂贵。

如果您正在进行指针、引用或基本值类型的赋值,我个人认为直接赋值会更快(渴望在profiler上看到结果)。在50%概率的环境中,您可能会执行更多的指令,将值放入寄存器。分配触发赋值运算符的结构或类对象将是最昂贵的。条件逻辑还引入了更多指令,并增加了代码复杂度指标。

最近我一直在阅读论文关于非常快的压缩技术,guys强调需要避免
if
分支以获得最佳性能。这是因为CPU流水线。使用
if
s会破坏CPU可以进行的许多优化,从而并行执行部分代码。因此,如果您有很多这样的操作,对我们来说可能会更快e
b=false

分支在现代CPU上很昂贵,而在嵌入式/旧CPU上内存访问也很昂贵。因此,除非您有某种奇怪的内存,写的时间比读的时间长(提示:您没有)

更糟糕的是,具体原因如下:

  • 一种分支指令。处理器可能会预测到这一点,但仍有可能产生开销
  • 2次内存访问,而不是1次。大多数形式的内存的读写速度都是一样的,那么,既然你能做一次,为什么还要做两次呢
  • 更多的代码开销。这是一个很小的开销,但是必须发出更多的指令才能执行
    if
    语句。这意味着额外的内存读取和缓存中不必要的空间消耗
  • 对于悲观,它可能意味着C++编译器决定将这个变量登记到寄存器中,而不是其他更必要的变量。
  • 另外,如果您假定
    b
    被放入寄存器中,那么寄存器读/写非常便宜,但它们不是免费的

在现代流水线处理器上,您需要考虑以下几点:

  • 预测失误的分支成本很高
  • 储存和装载需要很长时间
  • 缓存可能会加快读写速度,但如果它是多缓存体系结构,并且在多个缓存中修改
    b
    ,则多个写入可能意味着多个缓存收回,并可能会抵消缓存的性能
带条件写入的读取至少有一个内存访问和一个可能预测失误的分支。假设该分支占用50%的时间,则平均有1.5个内存访问,再加上预测失误的可能性

无条件写入只有一个内存访问,没有任何分支


现在,您需要平衡预测失误的成本和存储成本,存储成本的变化取决于您拥有的缓存代理的数量。

如果最终结果是b为假,那么b在逻辑上重要吗?@Fuzzy:这是关于优化,而不是逻辑。是的,但第二个更容易阅读,并且更容易说出我认为是什么n、 逻辑和优化总是交织在一起的,因为如果你做了一些快速但逻辑错误的事情,它不是很有用,是吗?这两个代码片段在逻辑上都是错误的。你看,它们在逻辑上是等价的。分支(错误)预测的好处在于,它是否仍然适用于ARM CPU,其中if()这样的函数是在没有任何分支的情况下实现的吗?由于额外的内存读取,它仍然会稍微慢一些。即使您有一些神奇的
读取并设置false if true
指令,处理器仍然必须从内存中读取值,以测试它是否为真。对于ARM上的分支,不,分支未命中并不真正适用y表示条件赋值。在x86
ccmov
中,我不相信没有分支。因此,R-W的大降落伞-分支预测失误-不适用于ARM。W的大降落伞-缓存刷新-仍然适用,不是吗?是的,这可能是真的。如果
b
没有移动到寄存器中(提示:一个好的编译器通常会对其进行优化并将其移动到寄存器中)因此对于ARM和其他具有内存缓存但没有分支预测的处理器,它可能会稍微慢一点。但是第二个版本的可读性要高得多,您可以立即知道它的用途。。
b = false;