为什么CUDA中没有简单的原子递增、递减操作?

为什么CUDA中没有简单的原子递增、递减操作?,cuda,increment,atomic,Cuda,Increment,Atomic,从: 读取全局或全局模式中地址地址处的32位单词旧 共享内存,计算((old>=val)?0:(old+1)),并存储 结果返回到同一地址的内存。这三项行动是: 在一个原子事务中执行。该函数返回old 这很好,很漂亮。但是他在哪里 它只是增加地址处的值并返回旧值?及 它只是增加地址处的值,而不返回任何值 注意:当然,我可以通过包装实际的API调用来“滚动我自己的”,但我认为硬件的操作非常简单,可能更便宜。他们没有实现简单的增加和减少操作,因为这些操作没有更好的性能。当前体系结构中的每条机器代码指

从:

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

这很好,很漂亮。但是他在哪里

它只是增加
地址处的值
并返回旧值?及

它只是增加
地址
处的值,而不返回任何值


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

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


我认为旧处理器上专用的
inc
dec
指令现在只是晶体管更昂贵、指令缓存更小的时代的产物,因此值得将指令编码为尽可能少的位。我的猜测是,在新的CPU上,
inc
dec
指令在内部是按照更通用的加法函数实现的,并且主要是为了向后兼容。

它们没有实现简单的递增和递减操作,因为这些操作不会有更好的性能。当前体系结构中的每条机器代码指令占用相同的空间量,即64位。换句话说,指令中有空间容纳完整的32位立即数,因为它们有支持添加完整32位值的原子指令,所以它们已经用完了晶体管


我认为旧处理器上专用的
inc
dec
指令现在只是晶体管更昂贵、指令缓存更小的时代的产物,因此值得将指令编码为尽可能少的位。我的猜测是,在新的CPU上,
inc
dec
指令是按照更通用的加法函数在内部实现的,主要是为了向后兼容。

您应该能够使用以下方法实现“简单”的原子增量:

__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);

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

您应该能够通过以下方式实现“简单”原子增量:

__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);

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

您能否围绕
atomicInc
构建包装器?例如,
unsigned int atomicInc2(unsigned int*address){atomicInc(unsigned int*address,address[0]+1);}
?@JackOLantern:请参见编辑。另外,您的意思是
0
而不是
address[0]+1
。为什么不直接使用
atomicAdd
?你没有说明为什么这是不可接受的。没什么可包的。此外,如果您不喜欢返回值,请不要使用它。这是一个稍加掩饰的咆哮,不是一个建设性的问题。投票结束。@RobertCrovella:回答这个问题,这样我就可以接受了?你能围绕原子公司构建包装器吗?例如,
unsigned int atomicInc2(unsigned int*address){atomicInc(unsigned int*address,address[0]+1);}
?@JackOLantern:请参见编辑。另外,您的意思是
0
而不是
address[0]+1
。为什么不直接使用
atomicAdd
?你没有说明为什么这是不可接受的。没什么可包的。此外,如果您不喜欢返回值,请不要使用它。这是一个稍加掩饰的咆哮,不是一个建设性的问题。投票关闭。@RobertCrovella:回答这个问题,这样我就可以接受了?但这不仅仅是对指令进行编码,它还返回旧值,并花时间将
val
old
等进行比较。我认为简单的增量可能更快,或者至少更快,API不应假定它不是。如果不关心值溢出,可以使用
atomicAdd
。它添加立即值,而不是将其用作重置点。但我确信这两部电影的表现是完全一样的。它们可能在内部以相同的逻辑实现,它们不是同一条指令的唯一原因是指令中没有空间容纳两个32位立即数。你可以说它们应该公开一条更简单的
atomicInc
指令,但这只有在它们认为可以的情况下才有意义最终在未来的GPU上实现该指令,这似乎不太可能。但它不仅仅是对指令进行编码,它还返回旧值,并花时间将
val
old
等进行比较。我认为简单的增量可能更快,或者至少更快,API不应假定它不是。如果不关心值溢出,可以使用
atomicAdd
。它添加立即值,而不是将其用作重置点。我相信这两个角色的表现是准确的