From 3aac8e34835808b596540c5a721457685dd24e56 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 27 Apr 2021 22:59:59 +0200 Subject: [PATCH] Add a RAII wrapper for enabling flush-to-zero --- src/common/utils.cpp | 10 ++++++++++ src/common/utils.h | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 0f1dac2e..25680d61 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -17,6 +17,7 @@ #include "utils.h" #include +#include #include namespace bp = boost::process; @@ -46,3 +47,12 @@ bool set_realtime_priority(bool sched_fifo, int priority) { return sched_setscheduler(0, sched_fifo ? SCHED_FIFO : SCHED_OTHER, ¶ms) == 0; } + +ScopedFlushToZero::ScopedFlushToZero() { + old_ftz_mode = _MM_GET_FLUSH_ZERO_MODE(); + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); +} + +ScopedFlushToZero::~ScopedFlushToZero() { + _MM_SET_FLUSH_ZERO_MODE(old_ftz_mode); +} diff --git a/src/common/utils.h b/src/common/utils.h index 0df56d6c..cbac74d0 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -83,3 +83,28 @@ std::optional get_realtime_priority(); * user does not have the privileges to set realtime priorities. */ bool set_realtime_priority(bool sched_fifo, int priority = 5); + +/** + * A RAII wrapper that will temporarily enable the FTZ flag so that denormals + * are automatically flushed to zero, returning to whatever the flag was + * previously when it drops out of scope. + */ +class ScopedFlushToZero { + ScopedFlushToZero(); + ~ScopedFlushToZero(); + + ScopedFlushToZero(const ScopedFlushToZero&) = delete; + ScopedFlushToZero& operator=(const ScopedFlushToZero&) = delete; + + ScopedFlushToZero(ScopedFlushToZero&&) = delete; + ScopedFlushToZero& operator=(ScopedFlushToZero&&) = delete; + + private: + /** + * The previous FTZ mode. When we use this on the Wine side, this should + * always be disabled. But, we'll make sure to do it correctly anyhow so we + * don't accidentally end up disabling FTZ somewhere where it should be + * enabled. + */ + unsigned int old_ftz_mode; +};