如何检测 macOS 上的外部 GPU (eGPU) 连接和断开连接?

How do I detect External GPU (eGPU) connection and disconnection on macOS?

我想编写一个 macOS 应用程序,它可以检测您何时通过 Disconnect "GPU Name" 额外菜单断开外部 GPU,然后采取一些措施。

来自苹果的Metal docs

Register for External GPU Notifications

Call the MTLCopyAllDevicesWithObserver function to get a list of all the Metal devices available to a system and register an observer that's called whenever this list changes (or may change due to a safe disconnect request).

id <NSObject> deviceObserver  = nil;
NSArray<id<MTLDevice>> *deviceList = nil;
deviceList = MTLCopyAllDevicesWithObserver(&deviceObserver,
                                           ^(id<MTLDevice> device, MTLDeviceNotificationName name) {
                                               [self handleExternalGPUEventsForDevice:device notification:name];
                                           });
_deviceObserver = deviceObserver;
_deviceList = deviceList;

To deregister the observer, call the MTLRemoveDeviceObserver function.

Respond to External GPU Notifications

Metal notifies your app about these external GPU events:

  • MTLDeviceWasAddedNotification. Metal posts this notification when an external GPU is added to the system. Evaluate the updated list of devices and consider using the new addition.

  • MTLDeviceRemovalRequestedNotification. Metal posts this notification when the user initiates a safe disconnect request for an external GPU. Your app has approximately one second to migrate work off the device and remove all references to it. If your app fails to do so, macOS notifies the user that your app is blocking the safe disconnect request.

  • MTLDeviceWasRemovedNotification. Metal posts this notification when an external GPU is removed from the system and your app still has references to that device. If the user safely disconnected an external GPU, Metal posts this notification after it posts a MTLDeviceRemovalRequestedNotification notification. If the user unexpectedly disconnected an external GPU, Metal posts this notification without first posting a MTLDeviceRemovalRequestedNotification notification. After an external GPU is removed, any command buffers queued for the device are completed with an error, and any new API calls that reference the device fail with an error.

Set up a method to respond to the notifications, and pass this method to the handler parameter of the MTLCopyAllDevicesWithObserver function.

- (void)handleExternalGPUEventsForDevice:(id<MTLDevice>)device notification:(MTLDeviceNotificationName)notification
{
    if (notification == MTLDeviceWasAddedNotification) {  }
    else if (notification == MTLDeviceRemovalRequestedNotification) {  }
    else if (notification == MTLDeviceWasRemovedNotification) {  }
}