[metal] Use the last command buffer for semaphore signaling This is an performance improvement over the previous case where we always create a new command buffer for semaphore signaling.
diff --git a/experimental/metal/metal_device.m b/experimental/metal/metal_device.m index a457343..ba11534 100644 --- a/experimental/metal/metal_device.m +++ b/experimental/metal/metal_device.m
@@ -365,29 +365,33 @@ [wait_command_buffer commit]; } - // Then commit all recorded compute command buffers. + // Then commit all recorded compute command buffers, except the last one, which we will patch up + // with semaphore signaling. + id<MTLCommandBuffer> signal_command_buffer = nil; for (iree_host_size_t i = 0; i < command_buffer_count; ++i) { iree_hal_command_buffer_t* command_buffer = command_buffers[i]; id<MTLCommandBuffer> handle = iree_hal_metal_direct_command_buffer_handle(command_buffer); - [handle commit]; + if (i + 1 != command_buffer_count) [handle commit]; + signal_command_buffer = handle; + } + if (signal_command_buffer == nil) { + signal_command_buffer = [device->queue + commandBufferWithDescriptor:device->command_buffer_descriptor]; // autoreleased } - // Finally create a new command buffer and encode signal commands for all signal semaphores. - if (signal_semaphore_list.count > 0) { - id<MTLCommandBuffer> signal_command_buffer = [device->queue - commandBufferWithDescriptor:device->command_buffer_descriptor]; // autoreleased - for (iree_host_size_t i = 0; i < signal_semaphore_list.count; ++i) { - id<MTLSharedEvent> handle = - iree_hal_metal_shared_event_handle(signal_semaphore_list.semaphores[i]); - [signal_command_buffer encodeSignalEvent:handle - value:signal_semaphore_list.payload_values[i]]; - } - [signal_command_buffer addCompletedHandler:^(id<MTLCommandBuffer> cb) { - // Now we can release all retained wait semaphores. - iree_hal_resource_set_free(resource_set); - }]; - [signal_command_buffer commit]; + // Finally encode signal commands for all signal semaphores. + for (iree_host_size_t i = 0; i < signal_semaphore_list.count; ++i) { + id<MTLSharedEvent> handle = + iree_hal_metal_shared_event_handle(signal_semaphore_list.semaphores[i]); + [signal_command_buffer encodeSignalEvent:handle + value:signal_semaphore_list.payload_values[i]]; } + + [signal_command_buffer addCompletedHandler:^(id<MTLCommandBuffer> cb) { + // Now we can release all retained resources. + iree_hal_resource_set_free(resource_set); + }]; + [signal_command_buffer commit]; } IREE_TRACE_ZONE_END(z0);