C++ - 带有和不带有 if 语句的奇怪时间测量
C++ - strange time measurements with and without if statement
我偶然发现两个等效增量语法之间存在奇怪的持续时间差异。
if(seed != state) ++i;
此表示法每 1048576 次迭代测量 2.25 毫秒
i += (seed != state);
每 1048576 次迭代需要 2.80 毫秒。
第二种表示法不应该比第一种快一点吗?
值得一提的是,种子 == 状态很少发生(2^32-1 次中有 1 次)。
感谢您的回答。
编辑:
我用 gcc C 编译器测试了同样的东西,第一个比第二个稍微快一点,但第二个与 C++ 编译器的速度相同。
if
版本产生条件分支指令。另一个只是将 bool 提升为 int 并添加它。
编辑:
我倾向于使用第一个,因为从技术上讲,标准不需要转换 (int)true
来生成 1
;它只需要导致 "not zero." 尽管在实践中,我从未见过 bool
到 int
的转换不使用 1
来实现 true
。
您永远不知道编译器做了什么来优化您的代码。分支预测实际上会使第一个更快。第二个取决于实际进行的比较,如果为真,结果将作为 1 添加到 i
(这取决于您的 CPU,但很可能)将引入 "dummy" 1-加载寄存器。
作为分支预测的结果,第一个可能有条件地不执行添加。第二个将添加每个周期,因为没有跳过添加的选项可用。比较的结果会一直加到 i.
我假设你会发现第一个不是执行添加每个循环,而是偶尔在分支预测失败时执行。
使用 if
语句,编译器可以将增量转换为条件执行语句(至少对于支持条件执行语句的处理器)。
第二个示例将始终执行加法 1 或零。
这是微优化,实际上取决于处理器及其支持系统(缓存、分支预测等)。例如,第二个示例可能更快,因为没有决策跳跃。第一个示例在具有分支预测的处理器上可能更快。在可以将代码片段放入指令缓存(并且不需要获取其他指令)的处理器上,两者之间的差异可以忽略不计。
令我惊讶的是代码执行以毫秒为单位。对于这些示例,大多数现代处理器应该以纳秒为单位执行。
我偶然发现两个等效增量语法之间存在奇怪的持续时间差异。
if(seed != state) ++i;
此表示法每 1048576 次迭代测量 2.25 毫秒
i += (seed != state);
每 1048576 次迭代需要 2.80 毫秒。
第二种表示法不应该比第一种快一点吗? 值得一提的是,种子 == 状态很少发生(2^32-1 次中有 1 次)。
感谢您的回答。
编辑: 我用 gcc C 编译器测试了同样的东西,第一个比第二个稍微快一点,但第二个与 C++ 编译器的速度相同。
if
版本产生条件分支指令。另一个只是将 bool 提升为 int 并添加它。
编辑:
我倾向于使用第一个,因为从技术上讲,标准不需要转换 (int)true
来生成 1
;它只需要导致 "not zero." 尽管在实践中,我从未见过 bool
到 int
的转换不使用 1
来实现 true
。
您永远不知道编译器做了什么来优化您的代码。分支预测实际上会使第一个更快。第二个取决于实际进行的比较,如果为真,结果将作为 1 添加到 i
(这取决于您的 CPU,但很可能)将引入 "dummy" 1-加载寄存器。
作为分支预测的结果,第一个可能有条件地不执行添加。第二个将添加每个周期,因为没有跳过添加的选项可用。比较的结果会一直加到 i.
我假设你会发现第一个不是执行添加每个循环,而是偶尔在分支预测失败时执行。
使用 if
语句,编译器可以将增量转换为条件执行语句(至少对于支持条件执行语句的处理器)。
第二个示例将始终执行加法 1 或零。
这是微优化,实际上取决于处理器及其支持系统(缓存、分支预测等)。例如,第二个示例可能更快,因为没有决策跳跃。第一个示例在具有分支预测的处理器上可能更快。在可以将代码片段放入指令缓存(并且不需要获取其他指令)的处理器上,两者之间的差异可以忽略不计。
令我惊讶的是代码执行以毫秒为单位。对于这些示例,大多数现代处理器应该以纳秒为单位执行。