【问题标题】:Why has atomicAdd not been implemented for doubles?为什么没有为双打实现 atomicAdd?
【发布时间】:2012-09-27 16:37:08
【问题描述】:

为什么没有将 atomicAdd() for doubles 明确实现为 CUDA 4.0 或更高版本的一部分?

来自CUDA programming guide 4.1的附录F第97页以下版本 atomicAdd 已实现。

int atomicAdd(int* address, int val);
unsigned int atomicAdd(unsigned int* address,
                       unsigned int val);
unsigned long long int atomicAdd(unsigned long long int* address,
                                 unsigned long long int val);
float atomicAdd(float* address, float val)

同样的页面继续给出一个用于双打的 atomicAdd 的小实现,如下所示 我刚刚开始在我的项目中使用它。

__device__ double atomicAdd(double* address, double val)
{
    unsigned long long int* address_as_ull =
                             (unsigned long long int*)address;
    unsigned long long int old = *address_as_ull, assumed;
    do {
        assumed = old;
old = atomicCAS(address_as_ull, assumed,
                        __double_as_longlong(val +
                               __longlong_as_double(assumed)));
    } while (assumed != old);
    return __longlong_as_double(old);
}

为什么不将上述代码定义为 CUDA 的一部分?

【问题讨论】:

  • 可能是因为它的每个用户都知道它的实现,因为它不是内置指令并且重试逻辑可能会受到活锁的影响(因为不能保证公平,线程只要有其他线程更新同一个变量,就会停止)。

标签: cuda


【解决方案1】:

编辑:从 CUDA 8 开始,双精度 atomicAdd() 在 CUDA 中实现,并在 SM_6X (Pascal) GPU 中提供硬件支持。

目前,没有 CUDA 设备在硬件中支持 atomicAdddouble 正如您所指出的,它可以在 64 位整数上以 atomicCAS 的形式实现,但是有一个不平凡的性能成本。

因此,CUDA 软件团队选择记录正确的实现作为开发人员的一个选项,而不是使其成为 CUDA 标准库的一部分。这样,开发人员就不会在不知不觉中选择他们不了解的性能成本。

旁白:我认为这个问题不应该以“不具建设性”的方式结束。我认为这是一个完全有效的问题,+1。

【讨论】:

  • 是的,但从技术上讲,您是极少数如何回答这个问题的人之一。虽然我已经说过为什么我认为这种方式很有意义,但只有你可以说这是否是 CUDA 团队选择这种方式的原因。 ;-) 无论如何,我不是反对这个问题的人。
  • 有很多 NVIDIA 人员阅读并回答了关于 SO 的 CUDA 问题(尤其是在我们的开发者论坛关闭的情况下),这一事实使得这样的问题有效。你本可以发表你的评论作为答案,它本来是正确的,我会赞成的。 :) 顺便说一句,我不认为你投反对票;我指的是结束问题的一票。
  • 我同意,这是一个完全有效的问题,CUDA 标头可以在软件中实现双原子。虽然它的制定方式为某些人触发了红灯,但我认为应该恢复这个决定!
猜你喜欢
  • 2015-07-14
  • 1970-01-01
  • 2012-04-29
  • 2017-05-30
  • 1970-01-01
  • 1970-01-01
  • 2020-01-06
  • 2015-09-25
  • 1970-01-01
相关资源
最近更新 更多