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调用,但我认为硬件操作更简单,可能更便宜。
答案 0 :(得分:3)
他们没有实现简单的增加和减少操作,因为操作没有更好的性能。当前体系结构中的每个机器代码指令占用相同的空间量,即64位。换句话说,指令中有足够的32位立即值,并且因为它们具有支持添加完整32位值的原子指令,所以它们已经花费了晶体管。
我认为旧处理器上的专用inc
和dec
指令现在只是晶体管价格昂贵且指令缓存很小的时候的工件,因此值得努力编码指令尽可能少。我的猜测是,在新的CPU上,inc
和dec
指令是在内部更通用的附加功能实现的,并且主要用于向后兼容。
答案 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是编程指南中关于原子的部分,它涵盖了各种函数和数据类型的计算能力支持。