-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve __crystal_once
performance
#15216
base: master
Are you sure you want to change the base?
Conversation
__crystal_once
performance
Codegen still declares an |
I'm also working on the codegen part (primarily to improve performance), but I think this shouldn't have any undefined behavior since the pointer is always cast into the enum type before accessing it, and a boolean has to be at least one byte in size. |
A cast doesn't cut it because LLVM is free to assume the unused bits in the flags are poison. |
@BlobCodes Very nice, thank you! 😍 @HertzDevil By poison you mean that the cast may feel safe, but that we'd be assuming some undefined behavior? LLVM doesn't make guarantees that the 7 other bits will be carried over, just that the value for an @straight-shoota That sounds safer, that'd need a new |
Co-authored-by: Sijawusz Pur Rahnama <sija@sija.pl>
We should keep the existing implementation around for compatibilty with older compilers. I'm wondering why this is even a |
The main performance improvement is from the inlined fast-check, which is also possible without using the enum. Removing the
Creating a new |
Sounds like a great idea to separate the two changes into separate PRs. That's in general, and also in particular if we can merge one without any prerequisites. |
Description
This PR significantly improves
__crystal_once
performance.I originally wrote this code for a custom crystal stdlib focused on microchips without
malloc
.While the previous implementation used an array to keep track of all variables currently being initialized, this one (ab)uses the given
flag
boolean pointer as an enum with three values to represent the "being initialized" state.Also, the previous implementation always used a mutex when accessing any const variable using
-Dpreview_mt
.This implementation instead has a fast path for the (very likely) scenario that the variable was already initialized which doesn't need a mutex.
Let's talk numbers
Benchmark code and results on my machine can be found here:
https://gitlab.com/-/snippets/4772439