Wiem, że "każda osnowa zawiera wątki kolejnych, rosnących identyfikatorów wątków z pierwszą osnową zawierającą wątek 0", więc pierwsze 32 wątki powinny znajdować się w pierwszej osnowie. Ponadto wiem, że wszystkie wątki w jednej osnowie są wykonywane jednocześnie na dowolnym dostępnym multiprocesorze strumieniowym.CUDA. Jak rozwinąć pierwsze 32 wątki, aby były wykonywane równolegle?
Jak zrozumiałem, z tego powodu nie ma potrzeby synchronizowania wątku, jeśli wykonywana jest tylko jedna osnowa. Jednak poniższy kod generuje błędną odpowiedź, jeśli usunę dowolny z __syncthreads()
w przedostatnim bloku if
. Próbowałem znaleźć przyczynę, ale skończyłem z niczym. Naprawdę mam nadzieję na twoją pomoc, więc możesz mi powiedzieć, co jest nie tak z tym kodem? Dlaczego nie mogę opuścić tylko ostatniego __syncthreads()
i uzyskać prawidłową odpowiedź?
#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. Używam GT560Ti