Improving performance of compiled code by using hardware instructions available on the runtime hardware
- Dominant language
- Python
- Stars
- 5.3k
- Forks
- 2.2k
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 74
Description
### What is the problem this feature will solve?
As I am looking into ways to improve astropy performance, I can see that using the new'ish compiler feature of function multi-versioning should improve the performance of compiled C code, while retaining the portability of wheels.
# Background
By default, GCC ensures that the compiled code can run on most hardware and only compiles for SSE2 on x86_64 systems (vast majority of the existing hardware that astronomers use). SSE2 was released in 2001, and since then, the CPUs have evolved significantly and provide a whole bunch of efficient (assembly) instructions. Of course, the highest performance could be extracted by writing specific functions for each targeted CPU but that would be insurmountable maintenance burden (even if we could take on converting the relevant functions).
# Proposed solution
GCC (and Clang, but with caveats) provides an option to generate many different specialised functions when the targeted function is annotated with an `__attribute__` and a list of target architectures.
For example, adding the following attribute and compiling with a recent gcc:
```c
__attribute__((target_clones("default,sse4.2,avx,avx2,avx512f,arch=skylake-avx512")))
double sum_square(const double *restrict arr, const int64_t N) {
double sum = 0.0;
//This can also be vectorized if using -Ofast
//or using #pragma omp simd reduction(+:sum) and compiling with -fopenmp-simd
for(int64_t i=0;i= GLIBC 2.23, according to [the docs](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-target_005fclones-function-attribute).
### Describe the desired outcome
Compiled C code within astropy uses the instructions available on the runtime CPU, rather than being restricted to instructions on 25 year-old hardware.
### Additional context
I will note that function multi-versioning only improves the used instructions and does not necessarily enable vectorization. That would require additional steps; for example, for the above example of the `sum_squares` - since there is a summation and that answer can change due to numerical round-off from vectorization and different order of summing, the compiler will not generate vectorized code for the loop **unless** `-Ofast` is used, or `-fopenmp-simd` is used along with a `#pragma omp simd reduction(+:sum)`. See the [godbolt link](https://godbolt.org/z/bE44Ej5PM) for more details (look for `vmulpd/vaddpd` instructions for vectorized code, and `vmulsd/vaddsd` instructions for unvectorized code on AVX+ instruction sets).
Contributor guide
Research direction
The issue names no files or tests. Start by locating astropy's compiled C code and its build configuration, then determine how compiler and platform support would be selected. Done means portable wheels retain compatibility while compiled code can dispatch to instructions supported by the runtime CPU.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- build-system, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100