У меня вопрос о синхронизации CUDA. В частности, мне нужно уточнить синхронизацию в операторах if. Я имею в виду, если я поместил __syncthreads() в область действия оператора if, попавшего на долю потоков внутри блока, что происходит? Я думал, что некоторые потоки останутся "навсегда", ожидая других потоков, которые не попадут в точку синхронизации. Итак, я написал и выполнил некоторый пример кода для проверки:
__global__ void kernel(float* vett, int n)
{
int index = blockIdx.x*blockDim.x + threadIdx.x;
int gridSize = blockDim.x*gridDim.x;
while( index < n )
{
vett[index] = 2;
if(threadIdx.x < 10)
{
vett[index] = 100;
__syncthreads();
}
__syncthreads();
index += gridSize;
}
}
Удивительно, но я заметил, что результат был довольно "нормальным" (64 элемента, blockize 32):
100 100 100 100 100 100 100 100 100 100 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
100 100 100 100 100 100 100 100 100 100 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
Итак, я немного изменил свой код следующим образом:
__global__ void kernel(float* vett, int n)
{
int index = blockIdx.x*blockDim.x + threadIdx.x;
int gridSize = blockDim.x*gridDim.x;
while( index < n )
{
vett[index] = 2;
if(threadIdx.x < 10)
{
vett[index] = 100;
__syncthreads();
}
__syncthreads();
vett[index] = 3;
__syncthreads();
index += gridSize;
}
}
И результат был:
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
Опять же, я ошибся: я думал, что потоки внутри оператора if после изменения элемента вектора останутся в состоянии ожидания и никогда не выйдут из области if. Итак... не могли бы вы прояснить, что случилось? Возникает ли поток после точки синхронизации разблокировать потоки, ожидающие барьера? Если вам нужно воспроизвести мою ситуацию, я использовал CUDA Toolkit 5.0 RC с SDK 4.2. Большое спасибо заранее.