标签: denormal-numbers

一种强大的、可移植的方法来将刷新非规格化设置为零?

我正在处理一些代码,这些代码使用内联 Intel X86_64 程序集来设置处理器的 SSE 标志,以包括“flush-denormal-to-zero”和“treat-denormals-as-zero:”,stmxcsr然后ldmxcsr.

我不太喜欢这种方法(我们将其表示为方法 1)。关于非正规化的维基百科页面建议了一些其他选项:

  1. 使用环境变量:
#include <fenv.h>
// ...
fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);
Run Code Online (Sandbox Code Playgroud)
  1. 使用 XMM 寄存器的标头之一:
#include <xmmintrin.h>
// ...
_mm_setcsr( _mm_getcsr() | 0x0040 | 0x8000 );
Run Code Online (Sandbox Code Playgroud)
  1. 使用更多标头和一些宏:
#include <pmmintrin.h>
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
#include <xmmintrin.h>
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
Run Code Online (Sandbox Code Playgroud)

...但我也不太喜欢这些。它们不在任何通用/标准库中;当然,它们是英特尔特定的。如果我使用 ARM 怎么办?我可能还想这样做。我也不确定其中哪些可以与哪个编译器一起使用(维基百科说其中一些它们“可以工作”)。

那么,我应该如何最好地告诉我的处理器将非正规数刷新为零?

注意:我的问题并没有真正区分 C 和 C++。我对 C++ 习惯用法感兴趣,但如果只有“C'ish”习惯用法,我可以接受。

c++ idioms ieee-754 denormal-numbers

5
推荐指数
0
解决办法
903
查看次数

cmpeqpd 有时会返回错误的值

出于某种原因,有时在我的程序中我看到

cmpeqpd xmm3,xmm0
Run Code Online (Sandbox Code Playgroud)

where xmm0 == {0x2cd000000000, 0x2cd000000000} andxmm3 == {0x0, 0x2011d0800000000} 恰好{0xffffffffffffffff, 0x0}在 xmm3 中返回,这是错误的,因为(double)0x0不等于(double)0x2cd000000000.

我注意到它只是偶尔发生。我已经用 rr 记录了程序的执行,以便一致地重现它。有趣的是,在一个超级简化的简单程序中,我无法再重现这个问题。我想知道,是否有任何隐藏的微架构状态可以改变 cmpeqpd (cmppd) 行为?

请注意,我检查了相应 ymm 寄存器中的高 128 位是否为零。

floating-point assembly sse avx denormal-numbers

3
推荐指数
1
解决办法
74
查看次数

标签 统计

denormal-numbers ×2

assembly ×1

avx ×1

c++ ×1

floating-point ×1

idioms ×1

ieee-754 ×1

sse ×1