“-ftrapv”和“-fwrapv”:效率更高哪个?

问题描述 投票:5回答:3

来自GNU的网站:

-ftrapv
This option generates traps for signed overflow on addition, subtraction, multiplication operations. 
-fwrapv
This option instructs the compiler to assume that signed arithmetic overflow of addition, subtraction and multiplication wraps around using twos-complement representation. This flag enables some optimizations and disables others.

我有两个问题。 1)哪些选项更适合性能? 2)当-ftrapv定义说它产生“陷阱”时,它意味着什么?这是否意味着例外? (我猜不是,但值得问。)

资料来源:https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Code-Gen-Options.html

c++ gcc g++ gnu integer-overflow
3个回答
8
投票

这两个选项的重点在于为优化器提供比通常更少的余地。因此,除非您在优化器中遇到错误,否则最快的应该是两者都不使用,优化器假定您的代码没有任何溢出,并且不会发出代码来处理溢出。

当-ftrapv定义说它产生“陷阱”时,它意味着什么?这是否意味着例外?

它并不意味着C ++异常。它是依赖于目标的,但假设是x86,这意味着GCC运行时库会引发SIGABRT,这通常会中止您的程序。在其他平台上,它可能会使用导致硬件异常的特殊CPU指令。它主要用于调试目的,也许在少数情况下是安全的,其中溢出后继续的风险大于程序突然终止的风险。


0
投票

如果有一种方法可以告诉编译器在溢出的情况下它可以从满足应用程序要求的所有可能行为中自由选择,那么将实现最佳性能。如果程序员可以确定程序永远不会接收任何导致溢出的输入,甚至可以想象的最故意 - 反复无常的溢出行为将满足要求,则将溢出作为UB处理将仅产生最佳行为。

如果编译器可以从大量可能的输出中任意选择是可以接受的,只要整体行为仍受限制,使溢出UB可能会产生源代码复杂性最差的全世界组合。运行时性能与-fwrapv相比,因为程序员必须在源代码中指定编译器为-fwrapv自动生成的所有操作。性能将低于使用不那么激进的优化器所能达到的效果,该优化器是围绕“产生任意数据但受限行为”的想法而设计的,但是gcc没有提供这样的选择。

编译器中的陷阱溢出比让溢出的计算换行要昂贵得多(或者 - 如果编译器允许 - 让它们被视为具有可能以非确定性方式运行的任意扩展精度),但有时可能是比在代码中手动捕获溢出更便宜。是否在编译器中捕获溢出是有用的取决于应用程序要求是否需要它。


0
投票

-ftrapv是最慢的,因为它需要添加额外的代码来检测和捕获有符号整数上几乎每个操作的溢出,除非编译器有足够的有关值范围的信息来证明操作不会溢出。

-fwrapv可能是下一个最慢的,因为它禁止某些优化假设值永远不会包装,但这种影响相当小,因此-fwrapv的性能通常与不提供这些选项中的任何一个相似甚至完全相同。

© www.soinside.com 2019 - 2024. All rights reserved.