C++ 始终分配vs检查相等和分配

C++ 始终分配vs检查相等和分配,c++,performance,C++,Performance,以下各项之间是否存在明显的性能差异: 如果(a!=b)a=b 和 a=b 当a和b都是相同的内置类型时,比如int或bool,或者可能是一个非常简单和小的struct 据我所知,第二个表达式每次都会写入内存(我认为这是一个比读取更重的操作),而第一个表达式只有在a和b不相等时才会这样做 或者可能取决于b值更改的频率 我知道这更像是一个“++I vs I++”的问题,我很好奇,不过这要看情况而定 对于x86 CPU,您的程序中涉及的操作成本大致如下: 非缓存读取(即从尚未缓存的RAM读取):~1

以下各项之间是否存在明显的性能差异:

如果(a!=b)a=b
a=b

a
b
都是相同的内置类型时,比如
int
bool
,或者可能是一个非常简单和小的
struct

据我所知,第二个表达式每次都会写入内存(我认为这是一个比读取更重的操作),而第一个表达式只有在
a
b
不相等时才会这样做

或者可能取决于
b
值更改的频率

我知道这更像是一个“++I vs I++”的问题,我很好奇,不过这要看情况而定

对于x86 CPU,您的程序中涉及的操作成本大致如下:

  • 非缓存读取(即从尚未缓存的RAM读取):~100个时钟
  • 缓存读取:3到10个时钟
  • 寄存器读取:1/2时钟(值非常粗略,因为没有这种单一操作“读取”)
  • 写入:不同且取决于,但通常为~1个时钟
  • 比较:如果编译器猜测“哪个分支将发生”是错误的(这称为“管道暂停”),则最多有5-10个时钟;否则为-1时钟
使用此信息,您可能可以进行一些猜测;-)


对于其他(非x86)台式机/服务器/移动CPU,数字会有所不同,但总体情况大致相同。

您可以自己做一些简单的基准测试来回答这个问题……这取决于您的代码。如果您关心这一级别的性能,那么上下文将更重要,例如:这一行代码的出现频率是多少,以及
a==b
与否的可能性大概是多少?显然,如果
a!=b
频繁,那么它比没有if
a=b
更昂贵。也就是说,如果您遇到代码性能问题,如果这行代码有很大的影响,我会非常惊讶。@Borgeader但关于分支预测或缓存,可能有一些有趣的观点,我想知道是不是case@Borgleader:这可能会让您认为它在复杂场景中的行为是相同的。不一定是这样。写的速度真的比非寄存器读的快吗?据我所知,可能也有写缓存丢失?或者,如果两者都被缓存,那么缓存的读是3到10,缓存的写是1,这真的是真的吗?@mambo_sun:写时间是一件我并不100%清楚的事情。我所知道的是,它可以实现为1个时钟(写入数据时不需要阻塞执行管道,只需将其置于“写入缓冲区”并可以继续),但另一方面,过多的写缓存未命中可能确实会导致内存总线过载,这将导致道路上其他作业的延误。因此,即使在缓存未命中的情况下,单次写入也可能是1个时钟,但这可能有点难以量化影响。@mambo_sun与读取不同,写入不会阻塞,因为没有任何东西依赖于它们(除非您立即从同一地址加载)。但这并不意味着他们是免费的。即使对于无序执行的处理器,它们也有一个可以完成多少重新排序的限制。如果写缓存未命中数据块的时间太长,它仍然会暂停执行管道。我认为您应该添加一个引用,从哪里获取这些数字。@bolov:虽然这些数字或多或少都是众所周知的,但我不知道它们有哪一个来源。如果有人知道,请随意编辑答案。