fenv_access
pragma
禁用 (on
) 或启用 (off
) 可能更改浮点环境标志测试和模式更改的优化。
语法
#pragma fenv_access (
{on
|off
})
注解
默认情况下,fenv_access
为 off
。 编译器假定代码无法访问或操作浮点环境。 如果不需要环境访问,编译器可以执行更多操作来优化浮点代码。
如果代码测试浮点状态标志、异常或设置控制模式标志,请启用 fenv_access
。 编译器禁用浮点优化,因此代码始终可以访问浮点环境。
/fp:strict
命令行选项自动启用 fenv_access
。 有关此浮点行为和其他浮点行为的详细信息,请参阅 /fp(指定浮点数行为)。
将 fenv_access
pragma 与其他浮点设置结合使用的方式存在限制:
除非启用了精确的语义,否则无法启用
fenv_access
。 精确语义可以通过float_control
pragma 或使用/fp:precise
或/fp:strict
编译器选项来启用。 如果未指定其他浮点命令行选项,则编译器默认为/fp:precise
。设置
fenv_access(on)
时,不能使用float_control
禁用精确语义。
fenv_access(on)
指令禁止生成浮点收缩,即结合浮点运算的机器指令。 fenv_access(off)
还原以前的收缩行为。 这是 Visual Studio 2022 中的新行为。 默认情况下,以前的编译器版本可以在 fenv_access(on)
下生成收缩。 有关浮点收缩的详细信息,请参阅 /fp:contract
。
具有 fenv_access
约束的优化类型如下:
全局公共子表达式消除
代码运动
常量折叠
其他浮点 pragma 指令包括:
示例
本示例将 fenv_access
设置为 on
以设置 24 位精度的浮点控制寄存器:
// pragma_directive_fenv_access_x86.cpp
// compile with: /O2 /arch:IA32
// processor: x86
#include <stdio.h>
#include <float.h>
#include <errno.h>
#pragma fenv_access (on)
int main() {
double z, b = 0.1, t = 0.1;
unsigned int currentControl;
errno_t err;
err = _controlfp_s(¤tControl, _PC_24, _MCW_PC);
if (err != 0) {
printf_s("The function _controlfp_s failed!\n");
return -1;
}
z = b * t;
printf_s ("out=%.15e\n",z);
}
out=9.999999776482582e-03
如果从上一个示例注释禁止 #pragma fenv_access (on)
,则输出不同。 这是因为编译器会进行编译时评估,而编译时评估不会使用控制模式。
// pragma_directive_fenv_access_2.cpp
// compile with: /O2 /arch:IA32
#include <stdio.h>
#include <float.h>
int main() {
double z, b = 0.1, t = 0.1;
unsigned int currentControl;
errno_t err;
err = _controlfp_s(¤tControl, _PC_24, _MCW_PC);
if (err != 0) {
printf_s("The function _controlfp_s failed!\n");
return -1;
}
z = b * t;
printf_s ("out=%.15e\n",z);
}
out=1.000000000000000e-02