AcademySoftwareFoundation / AcademySoftwareFoundation/OpenColorIO
Improving CPU performance via math-related compiler optimization flags
- Lingua principale
- C++
- Stelle
- 2.1k
- Fork
- 503
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
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:

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)
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Inizia con il file heavy_transform.zip allegato e i log dei test unitari CPU, quindi riproduci i risultati segnalati usando ocioperf e il file CLF con carico di calcolo elevato. Analizza i tre flag del compilatore e i test falliti relativi agli arrotondamenti su ARM e Intel. Il lavoro sarà considerato completato quando sarà documentata una decisione in merito alla sicurezza dei flag e all’opportunità di abilitarli, e i test pertinenti passeranno oppure le relative aspettative saranno riviste.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- cpp
- Ambito
- build-system, performance
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Da chiarire
- Idoneità per principianti
- 25/100