为什么在CUDA中没有简单的原子增量,减量操作?

时间:2013-11-12 14:27:27

标签: cuda increment atomic

来自CUDA Programming guide

unsigned int atomicInc(unsigned int* address,
                       unsigned int val);
     

读取位于全局或地址old的32位字address   共享内存,计算((old >= val) ? 0 : (old+1)),并存储   结果回到同一地址的内存。这三个操作是   在一个原子事务中执行。该函数返回old

这很好,花花公子。但是在哪里

unsigned int atomicInc(unsigned int* address);

只是增加address的值并返回旧值?和

void atomicInc(unsigned int* address);

只是增加address的值而不返回任何内容?

注意:当然我可以自己推动自己的'通过包装实际的API调用,但我认为硬件操作更简单,可能更便宜。

2 个答案:

答案 0 :(得分:3)

他们没有实现简单的增加和减少操作,因为操作没有更好的性能。当前体系结构中的每个机器代码指令占用相同的空间量,即64位。换句话说,指令中有足够的32位立即值,并且因为它们具有支持添加完整32位值的原子指令,所以它们已经花费了晶体管。

我认为旧处理器上的专用incdec指令现在只是晶体管价格昂贵且指令缓存很小的时候的工件,因此值得努力编码指令尽可能少。我的猜测是,在新的CPU上,incdec指令是在内部更通用的附加功能实现的,并且主要用于向后兼容。

答案 1 :(得分:1)

你应该能够使用:

完成“简单”的原子增量
__global__ void mykernel(int *value){
  int my_old_val = atomicAdd(value, 1);
}

同样,如果您不关心返回值,这是完全可以接受的:

__global__ void mykernel(int *value){
  atomicAdd(value, 1);
}

你可以用以下方式进行原子衰减:

  atomicSub(value, 1);

甚至

  atomicAdd(value, -1);

Here是编程指南中关于原子的部分,它涵盖了各种函数和数据类型的计算能力支持。