简体   繁体   English

算术运算和编译器优化

[英]Arithmetic operations and the compiler optimizations

I am contemplating a fixed-point arithmetic library, and in order to decide on how much optimization should be done by the library itself (through expression templates) I started questioning how much will already be done by the optimizer. 我正在考虑一个定点算术库,为了决定库本身应该做多少优化(通过表达式模板),我开始质疑优化器已经完成了多少工作。 Take the following example for instance: 以下面的示例为例:

//This is a totally useless function to exemplify my point
void Compare(FixedPoint a, FixedPoint b) {
   if(a/b>10) {
      ... do stuff
   }
}

Now, in this function, a typical implementation of the FixedPoint class will cause 现在,在这个函数中,将导致FixedPoint类的典型实现

if( ( (a_<<N) / b_) > (10 <<N) ) {
... do stuff
}

Where N is the number of fractional bits. 其中N是小数位数。 That expression could mathematically be transformed into: 该表达式可以在数学上转换为:

(a_ > 10*b_)

even though this transformation will not result in the same behavior when you consider integer overflow. 即使在考虑整数溢出时,此转换也不会导致相同的行为。 The users of my library will presumably care about the mathematical equivalence and would rather have the reduced version (possibly provided through expression templates). 我的库的用户可能会关心数学等价,而宁愿使用简化版本(可能通过表达式模板提供)。

Now, the question is: Will the optimizer dare do the optimization itself, even though the behavior is not strictly the same? 现在,问题是:即使行为不完全相同,优化器是否敢于进行优化呢? Should I bother with such optimizations? 我应该为这样的优化而烦恼吗? Note that such optimizations aren't trivial. 请注意,此类优化并非易事。 In reality, you rarely have to do any bit shifts when you're using fixed-point arithmetic if you actually do these optimizations. 实际上,如果您实际执行这些优化,则在使用定点算术时很少需要进行任何位移。

That will depend on whether the a_ and b_ types are signed or unsigned. 这取决于a_b_类型是有符号还是无符号。

In C and C++ signed overflow is technically undefined behavior, while unsigned overflow is done using two-complement arithmetic. 在C和C ++中,有符号溢出在技术上是未定义的行为,而无符号溢出是使用二补码算法完成的。

Nevertheless, some compilers refuse to optimize the that code because many programs rely on the two-complement behavior of the signed overflow. 然而,一些编译器拒绝优化该代码,因为许多程序依赖于签名溢出的双补码行为。

Good modern compilers will have an option to enable/disable this particular assumption: that signed integers won't overflow. 好的现代编译器可以选择启用/禁用这个特定的假设:有符号的整数不会溢出。 What option is the default will vary with the compiler. 什么选项默认值会随编译器而变化。

With GCC, for example, see options -fstrict-overflow/-fno-strict-overflow and the related warning -Wstrict-overflow . 例如,使用GCC,请参阅options -fstrict-overflow/-fno-strict-overflow和相关警告-Wstrict-overflow

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM