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
Use cache to reduce CI build time #15028
Comments
Sure, we can always try to optimize this part. |
@ArkadiuszMichalski |
@donho I just need to determine exactly which factors to take into account for each job. For testing I made a cache for installed Python libraries (because XML checking itself takes only 3 seconds and downloading/installing packages 20-30 seconds), which I personally cannot accept. In this case the factors are the OS name, Python versions and the libraries versions being installed, so the cache entry looks like this: When cache not exist: When cache exist: Something similar could be done for Scintilla and Lexilla files. For testing purposes I will try the same on Msys2 build because I have a better understanding of the individual stages of compilation here. We'll see what the actual time savings would be by using the cache. |
In fact, when it comes to compilation files, it is not that simple. I started digging deeper into the topic and found out that it can be solved in two main ways:
All this tools are available in
Additionally I changed where the cache for this program should be kept because I don't like the default location. The problem is that our I didn't modify anything, so the entire construction took only 12 seconds. It takes much longer to update Msys2. Here I modified the As I already mentioned, the entire cache for all makefiles is located in the same folder. I am unable to determine which entries are only for Scintilla/Lexilla. Is there anyone here who uses/has used Maybe it's possible to dynamically pass a different One more thing, I don't know if |
Okay, I found a way to cache only
In this way we can limit caching to the mentioned libraries (don't cache everything). Result without cache (compilation takes Result witch cache (compilation takes 2m 35s): A very nice reduction, considering that practically no one touches the |
GitHub Windows runners have 4 cores or threads so can run |
@nyamatongwe We set this automatically based on the notepad-plus-plus/PowerEditor/gcc/makefile Line 205 in c823ca8
But the actual profit probably depends on the current load of the entire system/machine. |
This change does not affect the compilation of the files, it just sets different variables for Scintilla/Lexilla, because I wanted to cache only them, and this cannot be achieved from outside because all these makefiles use the same variables (names).
But I have these observations when we use Ccache:
For the above reason I decide to not use Ccache (at least for Msys2 and Cmake jobs). I returned to the concept of caching Scintilla/Lexilla compilation results. Assuming that changing some previously determined factors will cancel the entire cache (so full compilation will run), we can do this:
I implemented this for Msys2 build and here are the results: Btw, for Msys2 job I still had to modify the makefile because we do not expose this condition $(BUILD_DIRECTORY), and I cannot invoke this action before restoring the cache. After restoring the cache, the build folder will be automatically created and then our makefile will not recreate the entire empty structure of this folder, so I have to invoke it manually.
This only adds one target at the end that can be called externally, it does not affect the work of the makefile in any way. Of course this could be added permanently to the makefile, but I don't think there's a need to do it just because we need it in GitHub Action. Something similar can be done for Cmake job. I'll try to do it today because I'm wondering the result compared to Ccache. Edit: We can invoke build directory rule without modifying the makefile:
|
Some results for cmake build:
Finally the reduction is noticeable. Any advice why setting I tried the following things:
or
or
I wanted to place the resulting files in a separate folder because by default they mix with the source files in the same folder. Anyone uses nmake and knows what the problem is? https://learn.microsoft.com/en-us/cpp/build/reference/running-nmake?view=msvc-170 |
There is no use of $(DIR_O)\UTF8DocumentIterator.obj:: ../../boostregex/UTF8DocumentIterator.cxx
$(CC) $(CXXFLAGS) -D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS -c ../../boostregex/UTF8DocumentIterator.cxx
# should include -Fo$(DIR_O)\ to be something like
$(DIR_O)\UTF8DocumentIterator.obj:: ../../boostregex/UTF8DocumentIterator.cxx
$(CC) $(CXXFLAGS) -D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS -c -Fo$(DIR_O)\ ../../boostregex/UTF8DocumentIterator.cxx |
GitHub Actions offers us a 10 GB cache that can be used for some optimizations. For example we can remember frequently downloaded/generated files to eliminate performing constantly repetitive work.
I checked some of our bottlenecks and here are my conclusions:
Msys2
andgcc/make
takes about 45-55 seconds. It's a bit more, but it's hard to improve. The problem is that when there are new versions ofgcc/make
, they can take up a lot of space after unpacking (for example, 60MB becomes 400MB). Cache forman/pacman
managers for downloaded packages (Msys2\var\cache
folder) does not improve much, because restoring from the cache is comparable to downloading itself, and then we still need to install the packages. Caching the entireMsys2
folder after update (and packing/extracting it to theD
drive for better performance) does not improve much, because such a package takes up 180MB (800MB after unpacking), which takes about 40 seconds (the problem here is the long recovery from the cache, not unpacking which takes only 7 seconds).We can still try to cache only the files that have changed after update, but a few seconds one way or another won't change much.
For the above reasons, I decided to skip both cases at this time because they do not improve much. Analyzing the topic further, I started looking for files that do not change often. The
Scintilla/Lexilla
libraries are an ideal candidate for this purpose. What if, after compiling them, we remember the result and restore it when nothing significant has changed? We will no longer have to constantly compile the same thing, which will certainly reduce the build time of all cases. A few solutions that are on my mind:master
) will be able to update the cache, so PRs will only be able to load the cache (this will prevent unnecessary garbage entries in the cache storage).Scintilla/Lexilla
, a new compiler version, or changes in configuration files that affect compilation. In all such cases, the entire compilation will be performed. Here some branch (mainlymaster
) will create a new cache for this specific case that future PRs can use (if they meet the same factors).Scintilla/Lexilla
file, we can consider what to do, whether we should cancel the entire cache or simply compile only the changed files. In practice, no one in PR changes these files, so it's still a marginal situation.[force nocache]
flag to skip the cache if necessary (e.g. if we want to see logs and warnings forScintilla/Lexilla
compiling).@donho What do you think about the cache for
Scintilla/Lexilla
? Should I try to implement this or would you prefer to always compile these files?The text was updated successfully, but these errors were encountered: