Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/cplusplus11/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 是否有可能仅为某些特定的C+生成{activate | de activate}SIGFPE+;11个代码段?_Linux_C++11_Exception_Floating Point_Ieee 754 - Fatal编程技术网

Linux 是否有可能仅为某些特定的C+生成{activate | de activate}SIGFPE+;11个代码段?

Linux 是否有可能仅为某些特定的C+生成{activate | de activate}SIGFPE+;11个代码段?,linux,c++11,exception,floating-point,ieee-754,Linux,C++11,Exception,Floating Point,Ieee 754,我正在Linux上用C++11编写一个路径跟踪器,用于光传输的数值模拟,我正在使用 #include <fenv.h> ... feenableexcept( FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW ); 标准C++在编译时不提供任何方法来标记它是否应该启用或禁用浮点捕获。事实上,该标准并不要求支持操作浮点

我正在Linux上用C++11编写一个路径跟踪器,用于光传输的数值模拟,我正在使用

#include <fenv.h>
...
feenableexcept( FE_INVALID   | 
                FE_DIVBYZERO | 
                FE_OVERFLOW  | 
                FE_UNDERFLOW );

<>标准C++在编译时不提供任何方法来标记它是否应该启用或禁用浮点捕获。事实上,该标准并不要求支持操作浮点环境,因此实现是否具有浮点环境取决于实现。标准C++以外的任何答案取决于您使用的特定硬件和软件,但您没有报告该信息。

在典型处理器上,通过更改处理器控制寄存器来启用和禁用浮点捕获。您不需要函数调用来实现这一点,但正如您在问题中所建议的那样,函数调用并不昂贵。实际指令可能会消耗时间,因为它可能需要处理器序列化指令执行。(现代处理器可能有数百条指令同时执行,有些正在解码,有些等待处理器内的一个子单元,有些处于不同的计算阶段,有些等待将结果写入通用寄存器,等等。更改控制寄存器时,处理器可能必须等待所有当前执行的指令ng指令以完成,然后更改寄存器,然后开始执行新指令。)如果您的硬件以这种方式运行,则无法绕过它。(对于这种常见的硬件,在不实际执行运行时指令以更改控制寄存器的情况下,不可能编译带或不带陷阱运行的代码。)


您可能可以通过批处理路径跟踪计算来减少时间开销,因此这些计算在组中执行,整个组的浮点控制寄存器只有两个更改(一个用于关闭陷阱,一个用于打开陷阱)。

是否希望在其他代码中打开浮点陷阱?默认情况下,浮点补漏白通常是禁用的,在这种情况下,路径跟踪代码已经禁用了浮点补漏白,并且没有必要在其他代码中启用浮点补漏白,除非您特别希望在其他代码中使用浮点补漏白。@ChristianPagot:处理器具有英特尔的“LDMXCSR”和“STMXCSR”等指令加载和存储控制寄存器。您通常不直接访问这些文件;FeenableeExcept例程会为您执行此操作。如果您直接访问它们,则需要使用编译器的特殊功能(如GCC的“asm”)来插入汇编代码或使用汇编语言源文件,并且您需要对编译器和操作系统有特定的了解,以便能够以它们支持的方式(或至少允许的方式)执行此操作。它一般没有意义;您可以只调用feenableexcept。@ChristianPagot:归根结底,对feenableexcept的实际函数调用并不昂贵,实现函数调用的指令的执行时间很短。处理器状态的改变代价高昂,当你改变浮动PONT陷阱设置时,你不能避免改变处理器状态。@克里斯蒂娜PaGoT和埃里克:ISO C和C++有<代码> > Trac-PrdMac STFC FunviAccess,在中,你应该使用代码Gen尊重FP环境可能不是默认的事实,而<代码> FESETEN()或
feenableexcept()
可能在同一函数中的不同语句之间使用,因此
x+y
不一定可以与另一个
x+y
进行CSE,例如,如果它们可能使用不同的舍入模式。或者,如果两次引发异常是一个明显的副作用。但是see说,浮点环境访问和修改只有在支持
#pragma STDC FENV_access
并将其设置为打开时才有意义。。。实际上,目前很少有编译器(如HP aCC、Oracle Studio或IBM XL)明确支持#pragma,但大多数编译器都允许对浮点环境进行有意义的访问。一些现代x86 CPU可能会重命名FP环境,允许您在不序列化的情况下对其进行更改。我在某个地方读到,自从Core2以来,Intel至少重命名了x87控制寄存器。我没有去寻找MXCSR(这可能不太经常需要,因为有特定的指令可以使用截断(C cast语义)转换为整数或使用当前舍入模式进行舍入。与SSE3之前的x87不同,SSE3中
int I=(int)fp;
需要将舍入模式更改为截断并返回)。但是,是的,CPU必须保持
ldmxcsr
按程序顺序运行的幻觉。
#include <fenv.h>

int main() {
    float a = 1.0f;

    fedisableexcept(FE_DIVBYZERO);   // disable div by zero catching

    // generates an inf that **won't be** catched
    float c = a / 0.0f;

    feenableexcept(FE_DIVBYZERO);   // enable div by zero catching

    // generates an inf that **will be** catched
    float d = a / 2.0f;

    return 0
}