-
Notifications
You must be signed in to change notification settings - Fork 7k
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
Kconfig is too slow #20104
Comments
Looking at sources.txt it seems that around half the sources are dependent on DT/HW properties and could be pruned. |
Pretty sure the parsing overhead is the only significant bit, but I could profile Kconfiglib is already pretty optimized, so no major gains left there I think. It's just that speedy Python is still slow, especially for stuff like parsing. One thing that might shave some time is to inline a bunch of stuff (Python has really high function call overhead, and methods are even worse), but I don't want to make the code too ugly. Note that Where's the other second spent by the way? |
Using a poor man's profiler I found these:
zephyr_module is slow because it calls "west list", which takes 100ms. But I was unable to find out why west list was so slow. west flash -h I have fixed, it was obsolete. I'll look into gen_defines.py later. Pruning via source "$(foo)" is acceptable, but I'd like to see some numbers demonstrating that this will be worth it. e.g. in drivers/clock_control/Kconfig we could do
|
Curious how pruning by source works? |
You use information known pre-Kconfig, like the environment variable ARCH, to just source the ARCH relevant to you, instead of sourcing all arch's. We can increase the amount of pruning if we make DT symbols more accessible, e.g. accessible through environment variables. |
Can run preprocessor functions in
The preprocessor runs during parsing. It's also used when expanding environment variables. The preprocessor has no idea that it's expanding a |
I haven't put any effort into making
|
By the way, we should really ask ourselves if we can live with that 0.5s. Setting up the environment for building the docs and running Kconfig tests is already painful. Another way to make things faster is to get rid of things that aren't needed in the Kconfig files, though I don't know how much stuff there's left. |
I'd just like to see that we actually know where those 500ms are going. If we know that then we can know whether it is reasonable or not. e.g. half of Kconfig sources can be pruned, but if the platform-specific sources are small, and in reality 90% of Kconfig options are platform-independent then we can live with not pruning that 10%. |
I could write a thingy that tallies up the time per file/directory later maybe. |
Caching could also be an option. If it's parsing Kconfig sources that is expensive. Then we could have a key-value database from a hash of a Kconfig source to a pre-parsed Kconfig datastructure. But again, we need to start by understanding where time is spent. |
I know that shaving some of this time off would be greatly appreciated by CI when we do 1000s of builds. |
Yeah, been thinking of that too. Think it might work to just do a single hash for all Kconfig files too, and unpickle or something. Think it'd get a bit messy though, because there's a ton of loops and stuff in the data structures.
Wonder if the parsed Kconfig could be reused. Kconfiglib is designed so that you can |
I think that #9406 could help reducing the amount of Kconfig flags and Kconfig parsing. |
Use the LibYAML-based yaml.CLoader if available instead of yaml.Loader, which is written in Python and slow. See https://pyyaml.org/wiki/PyYAMLDocumentation. This speeds up gen_defines.py from 0.2s to 0.07s on my system, for -DBOARD=hifive1. It should also make scripts/kconfig/kconfig.py faster, because it indirectly uses edtlib via scripts/kconfig/kconfigfunctions.py. yaml.CLoader seems to be available out of the box when installing with pip on Ubuntu at least. Helps with zephyrproject-rtos#20104. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Use the LibYAML-based yaml.CLoader if available instead of yaml.Loader, which is written in Python and slow. See https://pyyaml.org/wiki/PyYAMLDocumentation. This speeds up gen_defines.py from 0.2s to 0.07s on my system, for -DBOARD=hifive1. It should also make scripts/kconfig/kconfig.py faster, because it indirectly uses edtlib via scripts/kconfig/kconfigfunctions.py. yaml.CLoader seems to be available out of the box when installing with pip on Ubuntu at least. Helps with #20104. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
@SebastianBoe My comp is an old Core i7 2600k from 2012, so might not be a great comparison.~ |
@SebastianBoe Could you check if this works in the interactive Python prompt? If not, LibYAML (the C parser) isn't available. from yaml import CLoader |
It works. |
Weird... shaves of 0.13 seconds from |
Feel free to reopen if you still think it's too slow. Fixed the low-hanging YAML parsing fruit. Rest is probably mostly micro-optimization, and not that easy. |
Is your enhancement proposal related to a problem? Please describe.
Of the 1.5s or so that CMake spends in Configure-time and generation-time a third of this is spent in kconfig.py. This is longer than expected.
Describe the solution you'd like
I'd like to see some profiling and analysis describing, in human-readable words, what is going on in those 500ms. Also, if it is found that the time spent is proportional to the size of the Kconfig tree I'd like to see how much of the Kconfig tree is actually relevant to the chosen HW platform. If we could prune 80% of the tree due to HW incompatability then this would be interesting.
The text was updated successfully, but these errors were encountered: