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

Improve CI cache usage #6868

Merged
merged 10 commits into from
Oct 31, 2023
Merged

Improve CI cache usage #6868

merged 10 commits into from
Oct 31, 2023

Conversation

DomClark
Copy link
Member

Main changes:

  • Cache Homebrew downloads for Mac builds. I left this out of the original migration to GitHub Actions as the runners have a load of stuff in the download directory already, which bloats the cache unnecessarily. Now we clear the download cache at the start of each run, so we only cache those files that are downloaded during the run.

    In order to reduce cache quota usage, download caches are not keyed by branch and run ID, but keyed based on the versions of the dependencies installed. Therefore, a new cache is only created when the dependencies change, be that by a manual change to the dependency list, or a new version released upstream. This is achieved by using Homebrew's bundle feature, where the dependencies are stored in a Brewfile, and the Brewfile.lock.json file generated after installation is hashed to provide the cache key.

    The Brewfile installation is done with the environment variables HOMEBREW_NO_AUTO_UPDATE, HOMEBREW_NO_INSTALL_UPGRADE, and HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK set. This should make installation a little faster, and stop additional downloads using up our cache quota. GitHub update their images quite frequently, so this shouldn't result in us using anything too out of date.

  • Use a single (per architecture) long-term cache for vcpkg dependencies. This should considerably reduce vcpkg cache usage compared to the current per-run caching, and prevent the master caches from expiring as often, reducing the number of very slow MSVC builds.

    This is done similarly to the Homebrew caching, with the cache keyed on the hash of a dependency list file. In this case, we are now using vcpkg in manifest mode, which is the recommended usage these days, with the dependencies in vcpkg.json in the project root. However, the manifest file itself, rather than any output, is used as the hash input for the cache key. This is because installing packages is considerably more expensive than for Homebrew, so we suppress recompilation wherever possible. This is contrary to recommended practice, but isn't any worse than caching legacy mode dependencies (as we currently do), and gives us significantly better performance.

  • Use compiler caching with MSVC builds. We used to use clcache for this back in the AppVeyor days, but I didn't carry it over to GitHub Actions as it didn't appear to be working (I'm not sure whether it ever worked for us or not). These days, clcache appears to be abandoned, and ccache now works with MSVC, so I'm using that instead, which also gives us consistency across all build jobs. This required some CMake tweaks, which are either clear or explained in comments.

    This seems to be a bit unreliable - sometimes the cache is never hit, despite being restored successfully. I've seen this happen on both the x86 and x64 jobs, but in different runs. I don't know what the problem is, but I think it's still an improvement overall.

  • Improve ccache effectiveness for Linux and MinGW builds. The cache limit was too low in these cases, which resulted in evicting earlier entries as later files were compiled. Since LMMS builds in roughly the same order each time, those later entries were then evicted when the next build began. The result was a very low hit rate due to a lot of cache churning. I have addressed this by building with an unlimited cache size, then only trimming the cache at the end of the build. This ensures that the old cache entries remain available until the build has completed.

    This was not a problem for macOS builds, as they use a more modern version of ccache which compresses entries automatically, increasing the effective cache size. However, GitHub Actions compresses cached data anyway, so I have disabled ccache's compression for a probably imperceptible performance improvement, and consistency across jobs. Together with the MSVC ccache addition, this means that all build jobs now use ccache with the same configuration.

Other changes:

  • Update third-party actions to their latest releases - they were triggering warnings about outdated Node versions.
  • Clear ccache statistics at the beginning of each run - this makes it easier to tell how individual changes affect the performance of ccache. It's less useful for determining long-term performance, but since the caches can disappear at any point anyway, that was always going to be unreliable.
  • Explicitly use SDL2 on macOS - in Homebrew, sdl has been renamed to sdl12-compat, which depends on sdl2, which is therefore installed. Our CMake script then finds this SDL2 and doesn't bother searching for SDL1.2. As such, we no longer need to bother installing sdl, and can use sdl2 to get the same behaviour in a clearer and more efficient way.
  • Build FFTW with support for SSE, SSE2, AVX, and AVX2 in vcpkg. FFTW detects the processor features at run time, so this should be backwards-compatible with older machines. This should offer a small speed boost at the cost of a small amount of disk space.

The Brewfile and vcpkg.json files should make development on macOS and Windows easier too, as all current dependencies can be automatically installed. It also means we don't need to update the wiki for these operating systems when changing dependencies.

@sakertooth
Copy link
Contributor

sakertooth commented Sep 15, 2023

Just to verify, the MSVC builds are finishing in approximately one hour because it has to rebuild the cache with its dependencies right, and future runs wouldn't require an hour for MSVC?

@DomClark
Copy link
Member Author

That's correct, yes.

@sakertooth sakertooth linked an issue Sep 19, 2023 that may be closed by this pull request
@sakertooth sakertooth removed a link to an issue Sep 19, 2023
@sakertooth sakertooth added the CI Issues/pull requests regarding continuous integration(CI) system label Sep 21, 2023
@sakertooth sakertooth merged commit cd018c0 into LMMS:master Oct 31, 2023
9 checks passed
@DomClark DomClark deleted the actions-caching branch November 1, 2023 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI Issues/pull requests regarding continuous integration(CI) system
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants