So che "ogni warp contiene thread di ID thread incrementali consecutivi con il primo ordito contenente il thread 0", quindi i primi 32 thread dovrebbero essere nel primo warp. Inoltre, so che tutti i thread in un warp vengono eseguiti simultaneamente su qualsiasi multiprocessore streaming disponibile.CUDA. Come srotolare i primi 32 thread in modo che vengano eseguiti in parallelo?
Come ho capito, per questo motivo non è necessario sincronizzare i thread se viene eseguito un solo ordito. Ma il codice qui sotto produce una risposta errata se rimuovo uno qualsiasi dei __syncthreads()
nel penultimo blocco if
. Ho provato a trovare la causa ma non ho trovato nulla. Spero davvero il tuo aiuto, quindi potresti dirmi cosa c'è di sbagliato in questo codice? Perché non posso lasciare solo l'ultima __syncthreads()
e ottenere la risposta giusta?
#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);
...
}
P.S. Sto usando GT560Ti