原子函数(例如atomic_add
)在 CUDA 编程中广泛用于计数或执行求和/聚合。但是,与普通全局内存读/写相比,我找不到有关原子函数速度的信息。
考虑以下任务,我们要计算一个具有 256K 元素的浮点数组。每个元素是首先计算的 1000 个中间变量的总和。一种方法是使用atomic_add
; 而另一种方法是使用 256K*1000 临时数组作为中间结果,然后减少该数组(通过求和)。
使用原子函数的第一种方法比第二种方法快吗?
原子函数(例如atomic_add
)在 CUDA 编程中广泛用于计数或执行求和/聚合。但是,与普通全局内存读/写相比,我找不到有关原子函数速度的信息。
考虑以下任务,我们要计算一个具有 256K 元素的浮点数组。每个元素是首先计算的 1000 个中间变量的总和。一种方法是使用atomic_add
; 而另一种方法是使用 256K*1000 临时数组作为中间结果,然后减少该数组(通过求和)。
使用原子函数的第一种方法比第二种方法快吗?
在您的特定情况下,即使您没有提供具体的程序,也不需要了解原子操作和非原子操作之间的延迟或带宽差异来排除您的两种方法:它们都非常低效。
您应该让单个块处理单个输出变量(或少量输出变量),这样每 1,000 个中间变量的总和就不会通过全局内存执行。您可能想阅读 Mark Harris 的“经典”演示文稿:
获得基础知识。近年来,由于更新的硬件功能,这方面有所改进。有关最近的实际实现,请参阅CUB 库的块缩减原语。
也相关:CUDA:如何在 GPU 中将数组的所有元素求和为一个数字?
如果以这种方式实现,每个输出元素将只被写入一次。即使 1,000 个中间体的计算需要以某种方式分布在多个块中,无论出于何种原因您没有在问题中共享 - 您仍应将其分布在较小的数字上,而不是 1,000,以便全局内存写入结果占总计算时间的一小部分,除了原子加法之外,不值得打扰。