Repository navigation
Don't wait for the GPU when freeing memory - #720
Merged
Merged
Conversation
Kernels access memory indirectly, so a blocking free waits for all work submitted so far. Memory is mostly freed from finalizers, so that stalled whichever thread collected garbage for as long as unrelated kernels ran (~860 ms with a 1 s kernel), and deadlocked when that work waited for a task on the thread. On the rolling stack, free with the DEFER_FREE policy, which has the driver release the memory once the GPU is done with it. NEO only checks that when memory is freed again, so reclaiming memory now frees a small allocation after collecting garbage. That doesn't wait for the GPU either: reclaiming can happen inside any driver call, with locks held. The LTS stack doesn't honor the free policies and keeps synchronizing. Part of #717.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #720 +/- ##
==========================================
- Coverage 84.08% 82.49% -1.59%
==========================================
Files 52 51 -1
Lines 4386 4268 -118
==========================================
- Hits 3688 3521 -167
- Misses 698 747 +49 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Outside the LTS stack, pooled memory is now released with
ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_DEFER_FREEinstead of a blocking free. Because kernels access memory indirectly, a blocking free waits for all work submitted so far. From a finalizer, that stalled the thread (~860 ms behind a busy kernel in the measurements on #717), and it deadlocked when that work waited on a task on the same thread.NEO only processes its deferred-free list during a later free (or when an allocation fails), so memory released this way could stay allocated indefinitely.
sweep_deferred_freesfrees a small dummy host allocation with the deferring policy, which processes the list without waiting for the GPU. It runs where we try to get memory back: after each GC inretry_reclaim, after trimming the pools in_maybe_gc, and after the scratch hedge's GC.The LTS stack keeps the old behavior (synchronize, then a blocking free). NEO doesn't report which free policies it supports, so this relies on the rolling stack implementing
DEFER_FREE.Tests:
main);Part of #717. Not covered yet: the finalizer of a busy immediate command list still drains it, and the LTS path still blocks.