我知道“每个经线都包含连续的、递增的线程 ID,第一个经线包含线程 0”,因此前 32 个线程应该在第一个经线中。另外我知道一个warp中的所有线程都在任何可用的流式多处理器上同时执行。
据我了解,因此,如果只执行一个扭曲,则不需要线程同步。但是,如果我删除__syncthreads()
倒数第二个if
块中的任何一个,下面的代码会产生错误的答案。我试图寻找原因,但最终一无所获。我真的希望你的帮助,所以你能告诉我这段代码有什么问题吗?为什么我不能只离开最后__syncthreads()
得到正确答案?
#define BLOCK_SIZE 128
__global__ void reduce ( int * inData, int * outData )
{
__shared__ int data [BLOCK_SIZE];
int tid = threadIdx.x;
int i = blockIdx.x * blockDim.x + threadIdx.x;
data [tid] = inData [i] + inData [i + blockDim.x / 2 ];
__syncthreads ();
for ( int s = blockDim.x / 4; s > 32; s >>= 1 )
{
if ( tid < s )
data [tid] += data [tid + s];
__syncthreads ();
}
if ( tid < 32 )
{
data [tid] += data [tid + 32];
__syncthreads ();
data [tid] += data [tid + 16];
__syncthreads ();
data [tid] += data [tid + 8];
__syncthreads ();
data [tid] += data [tid + 4];
__syncthreads ();
data [tid] += data [tid + 2];
__syncthreads ();
data [tid] += data [tid + 1];
__syncthreads ();
}
if ( tid == 0 )
outData [blockIdx.x] = data [0];
}
void main()
{
...
reduce<<<dim3(128), dim3(128)>>>(dev_data, dev_res);
...
}
PS我用的是GT560Ti