MinGW gcc设置fp舍入模式
我正在使用gcc编译器,我希望能够快速更改sse舍入模式。如果在linux下编译,以下代码可以工作:MinGW gcc设置fp舍入模式,c,gcc,assembly,floating-point,mingw,C,Gcc,Assembly,Floating Point,Mingw,我正在使用gcc编译器,我希望能够快速更改sse舍入模式。如果在linux下编译,以下代码可以工作: #include <xmmintrin.h> unsigned int _mxcsr_up = _MM_MASK_MASK | _MM_ROUND_UP; unsigned int _mxcsr_down = _MM_MASK_MASK | _MM_ROUND_DOWN; unsigned int _mxcsr_n = _MM_MASK_MASK; void round_neare
#include <xmmintrin.h>
unsigned int _mxcsr_up = _MM_MASK_MASK | _MM_ROUND_UP;
unsigned int _mxcsr_down = _MM_MASK_MASK | _MM_ROUND_DOWN;
unsigned int _mxcsr_n = _MM_MASK_MASK;
void round_nearest_mode() {
asm (
"ldmxcsr %0" : : "m" (_mxcsr_n)
);
}
void round_up_mode() {
asm (
"ldmxcsr %0" : : "m" (_mxcsr_up)
);
}
void round_down_mode() {
asm (
"ldmxcsr %0" : : "m" (_mxcsr_down)
);
}
#包括
无符号整数_mxcsr_up=_MM_MASK_MASK | _MM_ROUND_up;
无符号整数_mxcsr_down=_MM_MASK_MASK | _MM_ROUND_down;
无符号整数_mxcsr_n=_MM_掩码_掩码;
无效圆形\u最近的\u模式(){
asm(
“ldmxcsr%0”:“m”(\u mxcsr\u n)
);
}
无效取整模式(){
asm(
“ldmxcsr%0”:“m”(\u mxcsr\u up)
);
}
无效四舍五入向下模式(){
asm(
“ldmxcsr%0”:“m”(\u mxcsr\u向下)
);
}
但当我在windows下使用MinGW编译它时,舍入模式没有改变。原因是什么?提供
\u MM\u ROUND\u UP
常量的标题也定义了相关指令的内部包装
通常,您应该检索旧值或ANDN要更改的位,然后应用新值。(例如,mxcsr&=~一些位
)。您不会发现很多只使用LDMXCSR而不先执行STMXCSR的示例
哦,我认为你的代码中的那部分实际上是错的。我没有研究过\u MM\u MASK\u MASK
是如何定义的,但它的名称包括单词MASK。你要用其他常数对它进行O型运算,而不是对它进行AND运算您可能每次都将MXCSR设置为相同的值,因为您正在使用\u MM\u MASK\u MASK
对所有内容进行ORing,我假设已设置了所有舍入模式位。
正如@StoryTeller指出的,您不需要内联asm或内部函数来更改舍入模式,因为x86硬件提供的四种舍入模式与C99:()中由
fenv.h
定义的四种模式相匹配,您可以使用它们进行设置
如果要动态更改舍入模式,并确保优化器不会将任何FP ops重新排序到舍入模式设置不同的位置,则需要#pragma STDC FENV_访问
。另见
使用
asm volatile
手动执行此操作仍然不会阻止CSE认为先前计算的x/y
是相同的值,并且不会在asm语句后重新计算它。除非您使用x
或y
作为从未实际使用过的asm语句的读写操作数。e、 g
asm volatile("" : "+g"(x)); // optimizer must not make any assumptions about x's value.
您可以将LDMXCSR放在同一个内联asm语句中,以确保舍入模式更改的点也是编译器将
x
视为已更改的点。如果您在托管环境中,t@StoryTeller我包括但我不能使用它的内容。我认为“if#GLIBCXX_USE_C99_FENV_TR1”的条件不满足,但我不知道为什么。将您的项目构建为C99。将-std=c99
添加到编译器调用中(或者如果使用IDE,则在项目选项中查找该选项)。是什么让您认为模式没有更改?你是如何测试这个的?@DavidWohlferd:我认为他真的没有改变取整模式,因为他是在对_MM_MASK_MASK_MASK_MASK进行排序,而不是对其进行AND运算。