代码之家  ›  专栏  ›  技术社区  ›  Seva Alekseyev

先读后写条件写vs.写

  •  6
  • Seva Alekseyev  · 技术社区  · 14 年前

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

    bool b;
    if(b)
        b = false;
    

    b = false;
    

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

    免责声明:这是一个好奇的问题,不是我真正面对的问题。

    7 回复  |  直到 14 年前
        1
  •  4
  •   Earlz    14 年前

    分支在现代CPU上很昂贵,而内存访问在嵌入式/旧CPU上很昂贵。所以,除非你有一个奇怪的内存,写的时间比读的时间长(提示:你没有),否则直接分配的单元总是会更快。

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

    • 分支指令。处理器可能会预测到这一点,但它仍然可能会带来开销。
    • 2次内存访问而不是1次。在大多数形式的记忆中,读和写的速度是一样的,所以为什么在你能做到一次的情况下读两次呢?
    • 更多的代码开销。这是一个微型的,但是必须发出更多的指令来执行 if 语句。所以意味着额外的几次内存读取和更多的空间不必要地消耗在缓存中。
    • 对于悲观,它可能意味着C++编译器决定将这个变量放入寄存器中,而不是其他更必要的变量。
    • 另外,如果你认为 b 被登记在册。寄存器读/写非常便宜,但它们不是免费的。
        2
  •  1
  •   newdayrising    14 年前

    为了得到实际的结果,在不同的架构上分析这一点肯定是值得的。

        3
  •  1
  •   Paul R    14 年前

    这取决于各种因素:

    • 分支的可预测性如何(在第一个场景中)
    • B是否已在寄存器中
    • 你用的是什么架构
        4
  •  1
  •   Carl Norum    14 年前

    除了评测建议之外,它还真的取决于什么内存在备份写请求——例如,如果它是内存映射的闪存设备,那么写操作可能会非常昂贵。

        5
  •  1
  •   pajton    14 年前

    最近我读了很多关于快速压缩技术的文章,大家都强调要避免 if 分支以获得最佳性能。原因是CPU流水线。使用 如果 s中断了cpu为并行执行部分代码而进行的许多优化。所以,如果你有很多这样的操作,使用起来可能更快 b = false .

        6
  •  1
  •   Nathan Fellman    14 年前

    在现代流水线处理器上,您需要考虑这一点:

    • 预测失误的分行要花很多钱
    • 储存和装载需要很长时间
    • 缓存可以加快读写速度,但如果是多缓存体系结构, b 正在多个缓存中修改,多个写入可能意味着多个缓存收回,并且可能会抵消缓存的性能。

    带条件写入的读取 至少 一个内存访问和一个可能预测失误的分支。假设分支占用了50%的时间,则平均有1.5个内存访问,外加预测失误的可能性。

    无条件写入 确切地 一个内存访问,没有任何分支。

    现在,您需要平衡预测失误的成本和存储成本,存储成本会根据您拥有多少缓存代理而变化。

        7
  •  0
  •   Fadrian Sudaman    14 年前

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