Skip to content
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

Increased performance significantly using incbin library #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

themarpe
Copy link

@themarpe themarpe commented Jun 6, 2020

Performance and memory usage improvement

Hi!
Big fan of CMakeRC library. Lately I've been working with it a lot and came up with an idea to use the incbin assembly directive to include binary data without the need to create the large character array in the intermediate source file.

I've used the following library: https://github.com/graphitemaster/incbin
Which is also license wise compatible to integrate it into this project.
This adds support for many compilers with exception of MSVC (See: https://github.com/graphitemaster/incbin#portability)
Their solution for MSVC is, to generate intermediate character array files for that case - which this library already does by default :)

I've added a try_compile test which tries to use the incbin library and it falls back to "compatibility mode" if it fails to do so successfully.

Please comment on any changes that would be required to improve this feature.

Performance Increase:

Running improved library with a compiler which supports incbin assembly directive yields enormous performance boost.

Running tests

Machine: i7-4700MQ, GCC 8.4.0, Ubuntu 18.04

Compatibility mode enabled (performance without this feature)

cmake .. -DCMRC_COMPATIBILITY_MODE=ON
time cmake --build . --parallel

Result: 9.675s <- Before

Compatibility off (by default)

cmake .. 
time cmake --build . --parallel

Result: 3.080s <- After

Memory usage:

On Raspberry Pi 3, I had issues using this library with ~5MB files, as the device ran out of available memory. With the above feature, it compiled successfully without any issues.

Running the included tests again with improved library:

/usr/bin/time -v cmake --build . --parallel

Memory usage
Before: 540MB
After: 86MB

@vector-of-bool
Copy link
Owner

vector-of-bool commented Jun 13, 2020

Sorry for the slow response. I've been on a break for a while.

I didn't know about incbin, but that's pretty cool! I didn't know most compilers/assemblers were able to do this.

If I pull it in, I'll want to do some cleanup since we don't need all of Incbin's functionality (e.g. CMakeRC is, for better or worse, C++-only, so we can remove some of the C/C++ toggles).

I also have been wanting to set up some proper CI for this project, but haven't had the time to get it done.

Also: Have you verified that at least the few tests pass on the common compilers?

@themarpe
Copy link
Author

themarpe commented Jun 13, 2020

Okay I'll clean up the incbin library in the upcoming days.

I've ran the tests on MinGW (Windows) and GCC on Linux. Otherwise I've successfully compiled a project using this changes with Clang as well.

Regarding CI, I think that you only have to register your project to Travis CI or some other provider, and I can try writing some .yml files for it. (Which will then be ran when I do a pull request)

@nanosonde
Copy link

@themarpe Github Actions would also be possible. https://github.com/vector-of-bool/cmrc/actions

@themarpe
Copy link
Author

@nanosonde thanks for the suggestion. I've played with Github Actions over the weekend and I must say I quite like them. Will try to find some time and write a matrix to build on Linux, Windows and macOS.

@vector-of-bool regarding modifying incbin library - as the changes would be minimal, maybe we should stick with having an exact content of a commit to be able to easily update to a new commit in case incbin gets an update? Apart from that should anything else be cleaned up?

Has anyone played with MSVC suites Resource Compiler? Maybe we can close the gap and use this tool if it is available?

@tambry
Copy link

tambry commented Feb 23, 2021

I tried to use this, but got consistent segfaults. The current master or the compatibility mode worked fine. I used a full LLVM 13 (master) toolchain (clang, libc++, compiler-rt). Don't have a repro, just a FYI. 🙂

@themarpe
Copy link
Author

@tambry thanks for the heads up. As of now I've been using this up to clang-11 on Ubuntu 20.04.
Hopefully nothing changed on latest LLVM.

Could you try creating an minimum example of failure? Or at least describe your setup?
Do tests pass with your current compiler?

@tambry
Copy link

tambry commented Feb 27, 2021

@themarpe Investigated and I'm no longer able to reproduce. Was probably caused by a dirty build directory.

From the few runs I did with this vs master the result seemed to be slightly longer build times. My use case has very few (10) small (few hundred bytes) files.
Have you measured the performance yourself in such cases?

@themarpe
Copy link
Author

themarpe commented Mar 1, 2021

@tambry I have not. Not sure why the build time would increase as its still 1 step less, but the overall generate+compile might just be faster as compiling/linking? the incbin directive.

If you find a reasonable cutoff a threshold can be made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants