算术运算和编译器优化
Arithmetic operations and the compiler optimizations
我正在考虑一个定点算术库,为了决定库本身(通过表达式模板)应该做多少优化,我开始质疑优化器已经做了多少。以以下示例为例:
//This is a totally useless function to exemplify my point
void Compare(FixedPoint a, FixedPoint b) {
if(a/b>10) {
... do stuff
}
}
现在,在这个函数中,FixedPoint
类的典型实现将导致
if( ( (a_<<N) / b_) > (10 <<N) ) {
... do stuff
}
其中,N
是小数位数。该表达式可以在数学上转换为:
(a_ > 10*b_)
即使当您考虑整数溢出时,此转换不会导致相同的行为。我的库的用户可能会关心数学等价性,并且更愿意使用精简版(可能通过表达式模板提供)。
现在,问题是:即使行为并不完全相同,优化器也敢自己进行优化吗?我应该为这样的优化而烦恼吗?请注意,这样的优化并非微不足道。事实上,如果你真的做了这些优化,那么当你使用定点算术时,你很少需要做任何比特移位。
这将取决于a_
和b_
类型是有符号的还是无符号的。
在C和C++中,有符号溢出在技术上是未定义的行为,而无符号溢出是使用双补运算完成的。
尽管如此,一些编译器拒绝优化该代码,因为许多程序依赖于有符号溢出的双补行为。
优秀的现代编译器可以选择启用/禁用这一特定假设:有符号整数不会溢出。默认选项随编译器的不同而不同。
例如,对于GCC,请参阅选项-fstrict-overflow/-fno-strict-overflow
和相关警告-Wstrict-overflow
。
相关文章:
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- C++编译器是否优化了顺序静态变量读取?
- VS2017调试器:没有地址,可能是由于编译器优化
- 何时允许编译器优化复制构造函数
- 编译器(Visual C++)如何优化按索引访问矢量元素?
- static_assert有助于优化编译器吗?
- 哪个优化编译器开关使调试非常困难
- 优化编译器可以添加std::move吗
- VisualStudio 优化编译器版本 19.00.23506.0 中存在明显的编译错误
- C++是否允许优化编译器忽略对 for 条件的副作用
- 优化编译器能否从 std::unique_ptr 中消除所有运行时成本
- Microsoft c++优化编译器不断崩溃
- 优化编译器如何决定何时展开循环以及展开多少循环
- 有一个很好的测试c++优化编译器
- Mac上的g++链接时间优化-编译器/链接器错误
- visual_itoa_s一直在杀死c++优化编译器,为什么?
- Microsoft C/C++ 优化编译器编译到什么
- 优化编译器消除bug