AcademySoftwareFoundation / AcademySoftwareFoundation/OpenColorIO

Improving CPU performance via math-related compiler optimization flags

Open
#1,774 6 comments 0 reactions 0 assignees View on GitHub
Needs Discussion
Dominant language
C++
Stars
2.1k
Forks
503
PR merge metrics
No merged PRs in 30d

Description

As is well known, there are some compiler flags that may be used to allow the optimizer to speed up CPU performance. One of these is called `-ffast-math`. However, that option has problems that make it unsuitable for use with OCIO. For example, it can sometimes change the floating-point behavior of applications that link to the library using it. It also includes options such as `-ffinite-math-only` which interfere with NaN handling mechanisms that OCIO uses.

However, there is a subset of options that `-ffast-math` turns on that are worth exploring as part of an option called `-funsafe-math-optimizations`. This turns on a set of several sub-optimizations. We found that turning on just three of these gives the same amount of speed-up as turning on `-ffast-math` (or `-funsafe-math-optimizations`).

These flags are: `-fno-signed-zeros`, `-freciprocal-math`, and `-fassociative-math`. Turning off any one of these prevents the others from being effective and there is no performance gain.

Using ocioperf with a custom CLF file that is heavy on calculation, using most of the OCIO transforms that include SIMD instructions, I get the following results:
![image](https://user-images.githubusercontent.com/105517825/222752590-bd63e3c7-f33f-4ce9-b63f-a13fcac466a2.png)

The result was about a 25% speed-up for the default processing path, using SIMD intrinsics. The pure C++ side saw minimal speed-ups, but that path is not typically used. These tests were done on an Apple Macbook Pro with an M1 processor. This was running in native ARM mode and using sse2neon to leverage Neon SIMD instructions.

We suspect that for the type of calculations done in OCIO, `-fno-signed-zeros`, and `-freciprocal-math` should be harmless. The `-fassociative-math` allows the compiler to re-order arithmetic operations and we suspect it is mostly harmless but needs more investigation.

Enabling the three flags causes a fair number of CPU unit tests to fail. Initial investigation seems to indicate these are all due to rounding differences. For example, a test comparing integer pixel values may be expecting exactly 32565. Without the flag, the floating-point result would be 32565.4982 and that would get rounded down to 32565. But with the flags, you'd get 32565.51 and that would get rounded up to 32566, causing the test to fail.

This is arguably more a problem with the OCIO tests that are doing exact comparisons of integer values rather than taking into account there may be very slight variations that could cause values near 0.5 to round one way or the other.

Note that these options seem to have much more benefit on the Mac/ARM than on Intel, where we saw less than a 10% speed-up (and in that test ``-fno-trapping-math`` was used too).

**We're logging this issue to collect feedback from the community as to whether you would like to see these options enabled in the OCIO build.**

------------------

I've attached the CLF file that I was using as well as the logs from the CPU unit tests.
[heavy_transform.zip](https://github.com/AcademySoftwareFoundation/OpenColorIO/files/10883252/heavy_transform.zip)

[no-signed-zeros - associative-math - reciprocal-math.zip](https://github.com/AcademySoftwareFoundation/OpenColorIO/files/10883260/no-signed-zeros.-.associative-math.-.reciprocal-math.zip)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.