如何在 Metal 中的线程组之间进行同步
How to synchronize between threadgroups in Metal
我想在 Metal 内核的线程组之间同步写入 MTLBuffer
。我尝试使用 atomic_uint
类型和 atomic_fetch_add_explicit
函数。这应该可行,但我的问题是我不知道如何解释 CPU 端的值。我更喜欢一种锁定机制,我可以使用它来同步从不同线程组写入同一缓冲区。是否存在不受原子类型约束的机制或其他一些解决方法?
我在 16 位浮点数转换中遇到了类似的问题。
您可以尝试通过从缓冲区中提取原始位来解释 CPU 端的值,与 atomic_uint 的内部格式进行比较,然后尝试使用获得的信息来重铸作为您需要的数据类型。当然是一种低级方法,但在没有其他方法的情况下有效。
锁定通常不起作用,因为并非所有线程组都必须同时处于活动状态。例如,如果您尝试实现自旋锁,您可能只是活锁,因为您的数据生产者可能尚未启动,假设一切都是相同的内核。锁定方案的另一个问题是您不能导致 GPU 阻塞或上下文切换,因此您只会浪费功率旋转,可能永远浪费时间,等待资源可用。
更喜欢将全局原子用于传统上使用原子操作的操作。例如,如果您想编写一个简单的 malloc() 从预分配的 MTLBuffer 进行子分配,您可以使用全局原子将 MTLBuffer 中的偏移量增加每次分配的大小。 Return旧的offset+MTLBuffer基地址作为分配的开始。
我想在 Metal 内核的线程组之间同步写入 MTLBuffer
。我尝试使用 atomic_uint
类型和 atomic_fetch_add_explicit
函数。这应该可行,但我的问题是我不知道如何解释 CPU 端的值。我更喜欢一种锁定机制,我可以使用它来同步从不同线程组写入同一缓冲区。是否存在不受原子类型约束的机制或其他一些解决方法?
我在 16 位浮点数转换中遇到了类似的问题。
您可以尝试通过从缓冲区中提取原始位来解释 CPU 端的值,与 atomic_uint 的内部格式进行比较,然后尝试使用获得的信息来重铸作为您需要的数据类型。当然是一种低级方法,但在没有其他方法的情况下有效。
锁定通常不起作用,因为并非所有线程组都必须同时处于活动状态。例如,如果您尝试实现自旋锁,您可能只是活锁,因为您的数据生产者可能尚未启动,假设一切都是相同的内核。锁定方案的另一个问题是您不能导致 GPU 阻塞或上下文切换,因此您只会浪费功率旋转,可能永远浪费时间,等待资源可用。
更喜欢将全局原子用于传统上使用原子操作的操作。例如,如果您想编写一个简单的 malloc() 从预分配的 MTLBuffer 进行子分配,您可以使用全局原子将 MTLBuffer 中的偏移量增加每次分配的大小。 Return旧的offset+MTLBuffer基地址作为分配的开始。