Subnormal Floats and Flush-to-Zero in GLSL
Hardware Flush-to-Zero (FTZ) directly dictates how graphics hardware processes subnormal floating-point numbers in OpenGL Shading Language (GLSL) shaders. While the IEEE 754 standard specifies gradual underflow for values between zero and the minimum normalized float, GPU architectures frequently bypass this by truncating tiny results directly to zero. This article examines the mechanics of FTZ, why GPUs employ it, its consequences on numerical accuracy and shader stability, and practical strategies for managing its effects in GLSL.
Understanding Subnormal Numbers
In 32-bit single-precision floating-point arithmetic
(highp float), a normalized number maintains an implicit
leading bit of 1 in its significand, representing values down to
approximately \(1.175 \times
10^{-38}\). When a non-zero calculation produces a magnitude
smaller than this threshold, standard IEEE 754 arithmetic shifts into
subnormal (or denormalized) representation by setting the exponent to
zero and using a leading bit of 0. This mechanism allows values to scale
down gracefully toward zero, preserving relative precision at the
extreme lower boundary of the format.
The Mechanism of Flush-to-Zero (FTZ)
Flush-to-Zero alters this behavior at the hardware level. When an arithmetic logic unit (ALU) encounters a subnormal result—or in some designs, a subnormal input (often paired with Denormals-Are-Zero or DAZ)—the hardware instantly forces the value to signed zero (\(+0.0\) or \(-0.0\)).
GPUs prioritize throughput, silicon area, and power efficiency over the strict corner-case compliance of general-purpose CPUs. Handling subnormal numbers under IEEE 754 rules requires complex multi-cycle normalization logic or microcode trap handling, both of which severely degrade pipeline throughput. By implementing FTZ, GPU hardware designers keep floating-point units small, fast, and uniform across thousands of parallel execution lanes.
GLSL Specification and Hardware Realities
The GLSL and OpenGL/Vulkan specifications grant hardware vendors wide latitude regarding precision. Unlike strict CPU floating-point standards, GLSL explicitly allows implementations to flush denormalized numbers to zero on input, during intermediate operations, or at output.
While modern desktop GPUs (such as modern NVIDIA, AMD, and Intel architectures) support full IEEE 754 compliance for 32-bit and 64-bit operations, FTZ remains common in:
- Mobile GPUs: Architectures like ARM Mali, Qualcomm Adreno, and Imagination PowerVR aggressively use FTZ to conserve power and die space.
- Half-Precision Operations (
mediump/ FP16): Subnormal handling is almost universally disabled for 16-bit floats, where normalized numbers only extend down to \(6.10 \times 10^{-5}\). - Performance Modes: Many graphics drivers default to FTZ unless explicit compiler flags or extensions require full IEEE 754 compliance.
Practical Impacts on Shader Execution
- Unexpected Division by Zero: A common mathematical
safeguard in GLSL involves adding or checking a small non-zero term
before division. If that term falls into the subnormal range and is
flushed to zero, the subsequent division triggers an undefined
division-by-zero state, producing
InforNaN. - Loss of Gradual Underflow in Iterative Solvers: Iterative calculations—such as raymarching distance estimators, physics simulations, and numerical integration—depend on gradual decay. Under FTZ, an accumulating value abruptly drops from approximately \(10^{-38}\) to \(0.0\), causing sudden truncation, visible stepping artifacts, or premature loop termination.
- Cross-Platform Discrepancies: Shaders developed on desktop hardware with native subnormal support may behave unpredictably or fail completely when deployed on mobile devices where FTZ is hardwired into the ALU.
Mitigating FTZ Issues in GLSL
To ensure stability across devices with varying FTZ implementations:
- Clamp to Explicit Minimums: Prevent values from
entering subnormal ranges by clamping denominators and thresholds to
safe normalized constants (e.g.,
max(abs(val), 1e-5)formediumpor1e-20forhighp). - Use Log-Space Representation: For calculations involving extreme dynamic ranges, such as photometric calculations or deep attenuation curves, compute in logarithmic space to maintain normalized exponents.
- Explicit Precision Qualifiers: Ensure variables
prone to underflow are declared with
highpto widen the normalized range, particularly in GLSL ES wheremediumpdrastically raises the underflow boundary.