faster-cpython / ideas

1.68k stars 48 forks source link

Use the restrict keyword to enable more compiler optimizations. #472

Open rhpvorderman opened 1 year ago

rhpvorderman commented 1 year ago

Currently the C99-introduced restrict keyword is used only once inside the CPython code base for int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr). CPython seems quite apt to adapt more use of the restrict keyword, as the GIL pretty much enforces single-threaded behaviour because of the reference counting. So it can be guaranteed relatively often that a data block is only changed through the pointer passed to the function. Example: PyBuffer_FillInfo.

On the other hand, I am aware that restrict can cause considerable headaches and the area it might be successfully applied in might be limited. I think restrict at least deserves to be mentioned, even if the idea will get shot down immediately. Currently no issues mention its use on the faster-cpython repository.

gvanrossum commented 1 year ago

What does that keyword do?

rhpvorderman commented 1 year ago

Wikipedia has a pretty good (and short) article on it: https://en.wikipedia.org/wiki/Restrict .

What it does is advertise to the compiler that the pointer provided is the only pointer to the datablock. In the normal situation a pointer may point to a datablock that can be manipulated by other parts of the program that run simultaneously. Hence when a pointer is accessed the underlying memory is accessed as well to make sure the correct value is loaded.

Using the restrict keyword, the compiler "knows" that the underlying memory is not going to change since the restrict pointer is the only access to the data. The value can therefore be stored in a register for example. This prevents unnecessary round trips to memory. Auto vectorization is also made possible by this as the compiler knows that by the time it has read my_array[0], my_array[1] will not have changed.

The catch is that restrict is just a keyword. Just because the programmer says that the data cannot be accessed simultaneously that does not make it true. Dilligence by the programmer is required.

chriselion commented 1 year ago

Here are a few other gamedev resources on restrict: Mike Acton: Demystifying The Restrict Keyword Christer Ericson: Game Development Memory Optimization (youtube, slides)

They're old (2006 and 2003) but still give good explanation of the motivation+benefits. However, the architectures they were targeting (PlayStation 2 and 3) were pretty unforgiving; it might not make as much of a difference on a modern out-of-order processor. It's not something you'd want to use indiscriminately everywhere, but it might help speed up performance-critical function where you can guarantee that the inputs don't overlap with the outputs.

jneb commented 1 year ago

What does that keyword do?

There's a pretty good description at https://en.cppreference.com/w/c/language/restrict