Skip to content

Commit 2b562ba

Browse files
committed
GPU Metal: wait for other streams in a command buffer of its own
StreamWaitForEvents encoded the waits into the stream's open command buffer, after whatever work had accumulated there. With the merger's SectorRefit on all streams, stream 0's buffer (its own 4 sectors of refit) then waited for the 7 other streams: on pbpb30 its GPU work ended 36 ms before the wait was satisfied, and the buffer stayed incomplete meanwhile. Commit the pending work first, so that every GPU-side wait sits at the start of a buffer with no work before it. The host drains the stream right after the waits anyway. pbpb30, M1 Max, 3 rounds of 10 events: 958.8 -> 959.7 ms/ev; 6 rounds of the same change as a runtime switch: 971.2 -> 961.3 ms/ev. Metal dumps byte-identical on pbpb30, sim5pp identical to the CPU.
1 parent 57490e0 commit 2b562ba

1 file changed

Lines changed: 5 additions & 0 deletions

File tree

‎GPU/GPUTracking/Base/metal/GPUReconstructionMetal.mm‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,11 @@ MetalMemRef metalResolve(const GPUReconstructionMetalInternals* internals, const
491491

492492
void GPUReconstructionMetal::StreamWaitForEvents(int32_t stream, deviceEvent* evList, int32_t nEvents)
493493
{
494+
// Encoded after the stream's pending work, the waits would keep its command buffer
495+
// from completing until the other streams are done: wait in a buffer of its own.
496+
if (mInternals->streamHasWork[stream]) {
497+
CommitStream(stream);
498+
}
494499
// Encode commands to wait for all the events
495500
id<MTLCommandBuffer> cb = mInternals->commandBuffers[stream];
496501
for (int32_t ei = 0; ei < nEvents; ei++) {

0 commit comments

Comments
 (0)