C++-带有和不带有if语句的奇怪时间测量

C++ - strange time measurements with and without if statement

本文关键字:测量 时间 if C++- 语句      更新时间:2023-10-16

我偶然发现了两个等效增量语法之间奇怪的持续时间差异。

if(seed != state) ++i;

该符号测量每1048576次迭代2.25毫秒

i += (seed != state);

并且这是每1048576次迭代2.80ms。

第二个符号不应该比第一个快一点吗?值得一提的是,种子==状态很少发生(在2^32-1次中的1次)。

谢谢你的回答。

编辑:我用gcc C编译器测试了同样的东西,第一个比第二个稍快,但第二个与C++编译器的速度相同。

if版本会产生一条条件分支指令。另一个只是将bool提升为int并添加它。

编辑:

我倾向于使用第一个

,因为从技术上讲,标准不需要转换(int)true来产生1;只需要得到"非零"。尽管在实践中,我从未见过boolint的转换不使用1来代替true

您永远不知道编译器如何优化代码。分支预测实际上会使第一个分支更快。第二个取决于实际进行的比较,如果结果为真(这取决于您的CPU,但很可能),则将结果添加到i中作为1。

使用if语句,编译器可以将增量转换为有条件执行的语句(至少使用支持有条件执行语句的处理器)。

第二个示例将始终执行1或0的加法。

这是微观优化,实际上取决于处理器及其支持系统(缓存、分支预测等)。例如,第二个例子可能更快,因为没有决策跳跃。第一个例子在具有分支预测的处理器上可能更快。在可以将代码片段放入指令缓存(并且不需要获取其他指令)的处理器上,两者之间的差异可以忽略不计。

我很惊讶代码的执行是以毫秒为单位的。对于这些例子,大多数现代处理器应该在纳秒内执行。

由于分支预测,第一个不能有条件地执行加法。第二个是在每个周期添加,因为没有跳过添加的选项。比较结果将始终添加到i.中

我假设您会发现,第一个循环不是执行add-every循环,而是仅在分支预测失败时偶尔执行。