commit 5d99c5ab534b3279e2a952a9301ac9136e468160
parent c6ae79fe2690fbae294823cada8a1a1320d8eb26
Author: Mike Oliphant <oliphant@nostatic.org>
Date: Mon, 27 Mar 2023 16:24:56 -0700
Added floating point denormal disabling (#149)
Diffstat:
2 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/NeuralAmpModeler/NeuralAmpModeler.cpp b/NeuralAmpModeler/NeuralAmpModeler.cpp
@@ -12,6 +12,7 @@
#include "NeuralAmpModeler.h"
#include "IPlug_include_in_plug_src.h"
// clang-format on
+#include "architecture.hpp";
using namespace iplug;
using namespace igraphics;
@@ -530,6 +531,11 @@ void NeuralAmpModeler::ProcessBlock(iplug::sample **inputs,
const size_t numFrames = (size_t)nFrames;
const double sampleRate = this->GetSampleRate();
+ // Disable floating point denormals
+ std::fenv_t fe_state;
+ std::feholdexcept(&fe_state);
+ disable_denormals();
+
this->_PrepareBuffers(numChannelsInternal, numFrames);
// Input is collapsed to mono in preparation for the NAM.
this->_ProcessInput(inputs, numFrames, numChannelsExternalIn,
@@ -621,6 +627,9 @@ void NeuralAmpModeler::ProcessBlock(iplug::sample **inputs,
irPointers = this->mIR->Process(toneStackOutPointers, numChannelsInternal,
numFrames);
+ // restore previous floating point state
+ std::feupdateenv(&fe_state);
+
// Let's get outta here
// This is where we exit mono for whatever the output requires.
this->_ProcessOutput(irPointers, outputs, numFrames, numChannelsInternal,
diff --git a/NeuralAmpModeler/architecture.hpp b/NeuralAmpModeler/architecture.hpp
@@ -0,0 +1,102 @@
+// From https://github.com/Dougal-s/Aether
+
+#ifndef ARCHITECTURE_HPP
+#define ARCHITECTURE_HPP
+
+// check cpu architecture
+
+#if /* x86_64 */ \
+ /* clang & gcc */ defined(__x86_64__) || \
+ /* msvc */ defined(_M_AMD64) \
+
+ #define ARCH_X86
+ #define ARCH_X86_64
+
+#elif /* i386 */ \
+ /* clang & gcc */ defined(__i386__) || \
+ /* msvc */ defined(_M_IX86) \
+
+ #define ARCH_X86
+ #define ARCH_I386
+
+#elif /* Arm64 */ \
+ /* clang & gcc */ defined(__aarch64__) || \
+ /* msvc */ defined(_M_ARM64) \
+
+ #define ARCH_ARM
+ #define ARCH_ARM64
+
+#elif /* Arm */ \
+ /* clang & gcc */ defined(__arm__) || \
+ /* msvc */ defined(_M_ARM) \
+
+ #define ARCH_ARM
+ #define ARCH_ARM32
+
+#else
+ #define ARCH_UNKNOWN
+#endif
+
+
+// check cpu extensions
+
+/* clang & gcc */
+#ifdef __SSE__
+ #define ARCH_EXT_SSE
+#endif
+
+#ifdef __SSE2__
+ #define ARCH_EXT_SSE2
+#endif
+
+#ifdef __SSE3__
+ #define ARCH_EXT_SSE3
+#endif
+
+/* msvc */
+#if defined(ARCH_X86_64)
+ #define ARCH_EXT_SSE
+ #define ARCH_EXT_SSE2
+
+ // msvc doesn't seem to have anything for sse3 so I am just assuming
+ // it is supported
+ #define ARCH_EXT_SSE3
+#elif defined(ARCH_I386)
+ #if _M_IX86_FP > 0
+ #define ARCH_EXT_SSE
+ #elif _M_IX86_FP > 1
+ #define ARCH_EXT_SSE3
+ #define ARCH_EXT_SSE2
+ #define ARCH_EXT_SSE
+ #endif
+#endif
+
+
+// misc functions
+
+#ifdef ARCH_EXT_SSE
+
+ #include <cfenv>
+ #ifndef FE_DFL_DISABLE_SSE_DENORMS_ENV
+ #include <immintrin.h>
+ #endif
+
+#endif
+
+inline void disable_denormals() noexcept {
+
+ #if defined(ARCH_EXT_SSE)
+ #ifdef FE_DFL_DISABLE_SSE_DENORMS_ENV
+ std::fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);
+ #else
+ _mm_setcsr(_mm_getcsr() | 0x8040);
+ #endif
+ #elif defined(ARCH_ARM)
+ #if __has_builtin(__builtin_arm_set_fpscr) && __has_builtin(__builtin_arm_get_fpscr)
+ __builtin_arm_set_fpscr(__builtin_arm_get_fpscr() | (1 << 24));
+ #endif
+ #endif
+
+}
+
+#endif