C++ Compilers

This page contains an overview of optimizations that C++ compilers can perform on C++ code that is common in Blend2D. It was decided that the source code should avoid hand-written optimizations that C++ compilers can do easily. These optimizations include vectorization of floating point computations and exclude vectorization of integral computations as these are trickier. Each item in the tables below has a link to a Compiler Explorer that can be used to verify the current status of the feature. We expect compilers to improve in the future and we would be happy to see the status of all features as resolved.

The current recommendation for compiling Blend2D is to use clang compiler on all platforms as it generates the best code. GCC is also fine, but doesn't optimize some critical parts as good as clang.

Basic Optimizations

Feature Clang GCC MSVC
Optimized initialization of data / structs Yes Yes Only 32-bit
Optimized reads/writes of small ints Yes Yes No

Scalar Floating Point Operations

Blend2D compiles with -fno-math-errno by default, but doesn't use -ffast-math as that is considered unsafe. With these options both GCC and Clang produce pretty good machine code for FP operations and rounding. MSVC doesn't have -fno-math-errno option so we use __pragma(float_control()) locally to make the code it generates a bit better, but in many cases it cannot compete with what GCC/Clang can do.

Feature Clang GCC MSVC
Optimized isnan() Yes Yes v19.22+ [link]
Optimized isnan() [multiple checks] Clang 9+ [link] Yes No
Optimized isinf() Yes Yes No
Optimized isfinite() Yes Yes No
Optimized min(), max(), and conditional expressions Yes Yes Yes
Optimized nearbyint() Yes GCC 9+ No
Optimized trunc() Yes Yes No
Optimized floor() Yes Yes #pragma
Optimized ceil() Yes Yes #pragma
Optimized sqrt() Yes Yes #pragma
Optimized fma() Yes Yes #pragma

Vector Floating Point Operations

Blend2D expects C++ compiler to automatically vectorize computations that happen in pairs. Some data structures like BLPoint are used as like they were 128-bit SIMD registers representing two double precision floating points.

Feature Clang GCC MSVC
Vectorized addition Yes Yes v19.20+
Vectorized subtraction Yes Yes v19.20+
Vectorized multiplication Yes Yes v19.20+
Vectorized division Yes GCC 8 regresses v19.20+
Vectorized min() / max() Yes No No
Vectorized abs() Yes Yes v19.20+
Vectorized sqrt() Clang 6+ GCC 7+ No
Vectorized lerp() Yes GCC 7+ No
Vectorized affine matrix multiplication Clang 7+ No No
Vectorized evaluation of quadratic curve Clang 7+ GCC 9+ No
Vectorized evaluation of cubic curve Clang 7+ GCC 9+ No
Vectorized extrema of quadratic curve Clang 7+ No No
Vectorized computation of unit vector Yes No No
Vectorized intersection of two lines No No No