astropy / astropy/astropy

Improving performance of compiled code by using hardware instructions available on the runtime hardware

Open
#16,902 19 comments 0 reactions 0 assignees View on GitHub
convolution Feature Request Performance stats timeseries
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.