我已经在网上搜索无济于事。
Xcode 和 Visual C++ 有没有办法将非规范化数字视为 0?我原以为IDE首选项中有一个选项可以打开此选项,但似乎找不到。
我正在做一些跨平台的音频工作,需要阻止某些处理器占用资源。
干杯
我已经在网上搜索无济于事。
Xcode 和 Visual C++ 有没有办法将非规范化数字视为 0?我原以为IDE首选项中有一个选项可以打开此选项,但似乎找不到。
我正在做一些跨平台的音频工作,需要阻止某些处理器占用资源。
干杯
您正在寻找一种平台定义的方式来在 MXCSR 寄存器中设置 FTZ 和/或 DAZ(在带有 SSE 或 x86-64 的 x86 上);见https://stackoverflow.com/a/2487733/567292
通常这被称为类似_controlfp
; Microsoft 文档位于http://msdn.microsoft.com/en-us/library/e9b52ceh.aspx
您还可以使用_MM_SET_FLUSH_ZERO_MODE
宏: http: //msdn.microsoft.com/en-us/library/a8b5ts9s (v=vs.71).aspx - 这可能是最跨平台的可移植方法。
为了全局禁用非规范化,我使用这两个宏:
//warning these macros has to be used in the same scope
#define MXCSR_SET_DAZ_AND_FTZ \
int oldMXCSR__ = _mm_getcsr(); /*read the old MXCSR setting */ \
int newMXCSR__ = oldMXCSR__ | 0x8040; /* set DAZ and FZ bits */ \
_mm_setcsr( newMXCSR__ ); /*write the new MXCSR setting to the MXCSR */
#define MXCSR_RESET_DAZ_AND_FTZ \
/*restore old MXCSR settings to turn denormals back on if they were on*/ \
_mm_setcsr( oldMXCSR__ );
我在过程开始时调用第一个,最后调用第二个。不幸的是,这在 Windows 上似乎效果不佳。
要在本地刷新非正规我使用这个
const Float32 k_DENORMAL_DC = 1e-25f;
inline void FlushDenormalToZero(Float32& ioFloat)
{
ioFloat += k_DENORMAL_DC;
ioFloat -= k_DENORMAL_DC;
}
为此,请在程序启动期间使用 Intel Intrinsics 宏。例如:
#include <immintrin.h>
int main() {
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
}
在我的 MSVC 版本中,这发出了以下汇编代码:
stmxcsr DWORD PTR tv805[rsp]
mov eax, DWORD PTR tv805[rsp]
bts eax, 15
mov DWORD PTR tv807[rsp], eax
ldmxcsr DWORD PTR tv807[rsp]
MXCSR 是控制和状态寄存器,此代码设置第 15 位,打开清零模式。
需要注意的一件事:这只影响计算产生的非规范化。如果您还想将 denormals 用作input时将它们设置为零,则还需要使用以下命令设置 DAZ 标志(denormals 为零):
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
另请注意,您需要为每个线程设置 MXCSR,因为包含的值对于每个线程都是本地的。