Search guides and the APICtrl K
  1. API reference
  2. DSP

denormals.h

ScopedNoDenormals: turn off denormal arithmetic for the length of a block.

#include <sonore/denormals.h>
On this page

Design notes

What this costs when it is missing

A denormal is a floating-point number too small to represent normally, and on x86 the hardware handles them in microcode rather than in the pipeline. The result is not a rounding difference; it is a stall.

Measured on the machine this was written on, eight biquads decaying through silence:

denormals allowed :   5.80 ms
FTZ + DAZ set     :   2.06 ms
ratio             :   2.82x

Nearly three times the CPU, for audio nobody can hear -- the tail of a filter forty decades below full scale. And it appears exactly when a track goes quiet, so the plugin that spikes is the one that was doing nothing.

Why the per-sample flush is not enough

dsp.h has flushDenormal(), and the SDK's own filters call it. That protects the code that remembers to call it. It does nothing for a DSP somebody generates tomorrow, and the whole point of this SDK is that the DSP is written by something other than a person who knows about denormals.

A processor-wide flag protects everything in the block, including the arithmetic nobody thought about.

Why it is scoped

The audio thread belongs to the HOST. Leaving its floating-point mode changed after returning would alter arithmetic in code we do not own -- and silently, since flush-to-zero changes results rather than failing. Saved on entry, restored on exit, including when the block throws.

Types 1

Flush-to-zero for as long as this object lives.

Declare one at the top of a process block. It is a handful of cycles to set and a handful to restore, against a stall of hundreds of cycles per denormal operation.

↑↓ to move↵ to openEvery public name in the headers, and every guide