Repository navigation
Avoid invalidating Base's condition code with YieldingSpinLock - #35
Merged
Merged
Conversation
Defining `Base.assert_havelock` and `islocked` for `YieldingSpinLock` invalidated the code Base compiled for `GenericCondition`s with an unknown lock type (about 270 method instances on Julia 1.13, 490 on nightly). As a result, every process loading GPUToolbox recompiled `Base.Filesystem.temp_cleanup_atexit` at exit, which takes about 100 ms. On Julia 1.13+, make `YieldingSpinLock` an `AbstractSpinLock` with the `owned` field Base's methods expect, and only override `lock`. That reuses Base's `trylock`, `unlock`, `islocked` and `assert_havelock` methods, so loading the package no longer invalidates anything. Older versions keep the wrapper around `SpinLock`; there, the invalidations are minor and do not cause the exit-time recompilation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
YieldingSpinLock(used byCompletion) definedBase.assert_havelockandislockedmethods. On Julia 1.13+ that invalidatesBase.assert_havelock(::GenericCondition), which Base compiled for conditions with an unknown lock type, plus everything depending on it throughwait/notify. One visible consequence: every process loading GPUToolbox (and so GPUArrays, CUDA.jl, oneAPI.jl, ...) recompilesBase.Filesystem.temp_cleanup_atexitat exit.julia -e 'using GPUToolbox'before(Invalidations from SnoopCompile's
@snoop_invalidations using GPUToolbox; timings are medians of 30 interleaved runs on a loaded machine. On 1.13,--trace-compile-timingshowstemp_cleanup_atexittaking about 100 ms to recompile at exit.)The fix: on 1.13+,
YieldingSpinLockis aThreads.AbstractSpinLockwith theownedfield that Base's spin lock methods expect, and only overrideslock. That way it reuses Base'strylock,unlock,islockedandassert_havelock, and no new methods reach the poorly-inferred condition code. Earlier versions keep the current wrapper aroundSpinLock: there is noAbstractSpinLock, and the remaining invalidations are minor and don't cause the exit-time recompilation. The tests now also check thatassert_havelockstill throws when the lock isn't held.