我正在 CUDA 中做一些原子实验。我的大问号是,当在同一个块中运行的两个线程以原子方式访问同一个地址时,它们的行为如何。我用 atomicAdd 进行了一些测试,它以原子方式工作,但是当我使用 atomicCAS 尝试下面的代码时,结果不是我所期望的。有人有解释吗?
#include <cuda_runtime.h>
#include <iostream>
#include <cuComplex.h>
using namespace std;
__global__ void kernel(int * pointer)
{
*pointer=0;
*(pointer+threadIdx.x+1)=0;
__syncthreads();
*(pointer+threadIdx.x+1)=atomicCAS(pointer,0,100);
}
int main(int argc,char ** argv)
{
int numThreads=40;
dim3 threadsPerBlock;
dim3 blocks;
int o[numThreads+1];
int * pointer;
cudaMalloc(&pointer,sizeof(int)*(numThreads+1));
cudaMemset(pointer,0,sizeof(int)*(numThreads+1));
threadsPerBlock.x=numThreads;
threadsPerBlock.y=1;
threadsPerBlock.z=1;
blocks.x=1;
blocks.y=1;
blocks.z=1;
kernel <<<threadsPerBlock,blocks>>> (pointer);
cudaMemcpy(o,pointer,sizeof(int)*(numThreads+1),cudaMemcpyDeviceToHost);
for (int i=0;i<numThreads+1;i++)
cout << o[i] << " ";
cout << endl;
}
在上面的代码 atomicCAS 在同一块内运行访问相同的地址以进行比较和交换......我的期望是只有一个 atomicCAS 会找到与 0 比较的值,而所有其他人会发现它 100,但奇怪的是输出我的程序是:
100 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
即所有线程都找到要比较的值设置为0。