2015-06-30 2 views
1

Мне нужно некоторое разъяснение относительно использования dim3 для установки количества потоков в моем ядре CUDA.Cuda блок/размеры сетки: когда использовать dim3?

У меня есть изображение в виде массива 1D поплавка, который я копирование на устройство с:

checkCudaErrors(cudaMemcpy(img_d, img.data, img.row * img.col * sizeof(float), cudaMemcpyHostToDevice)); 

Теперь нужно установить размеры сетки и блоков, чтобы запустить мое ядро:

dim3 blockDims(512); 
dim3 gridDims((unsigned int) ceil(img.row * img.col * 3/blockDims.x)); 
myKernel<<< gridDims, blockDims>>>(...) 

Мне интересно: в этом случае, поскольку данные 1D, имеет значение, если я использую структуру dim3? Любые преимущества по сравнению с использованием

unsigned int num_blocks = ceil(img.row * img.col * 3/blockDims.x)); 
myKernel<<<num_blocks, 512>>>(...) 

вместо этого?

Кроме того, я понимаю правильно, что при использовании DIM3, я буду ссылаться на идентификатор потока 2 индексов внутри моего ядра:

int x = blockIdx.x * blockDim.x + threadIdx.x; 
int y = blockIdx.y * blockDim.y + threadIdx.y; 

И когда я не использую DIM3, я буду использовать один индекс?

Большое спасибо,

ответ

3

, как вы договоритесь данные в памяти независимо от того, как вы бы настроить темы вашего ядра.

Память всегда является 1D непрерывным пространством байтов. Тем не менее, шаблон доступа зависит от того, как вы интерпретируете свои данные, а также как вы обращаетесь к ним с помощью 1D, 2D и 3D блоков потоков.

dim3 - целочисленный векторный тип на основе uint3, который используется для указания размеров. При определении переменной типа dim3 любой компонент, оставшийся неуказанным, инициализируется значением 1.

То же самое происходит и для блоков и сетки.

Подробнее на: http://docs.nvidia.com/cuda/cuda-c-programming-guide/#dim3

Итак, в обоих случаях: dim3 blockDims(512); и myKernel<<<num_blocks, 512>>>(...) вы всегда будете иметь доступ к threadIdx.y и threadIdx.z.

как нить идентификаторы начинаются с нуля, можно вычислить положение памяти в виде строки основного порядка, используя также y измерение:

int x = blockIdx.x * blockDim.x + threadIdx.x; 
int y = blockIdx.y * blockDim.y + threadIdx.y; 

int gid = img.col * y + x; 

, потому что blockIdx.y и threadIdx.y будет равен нулю.

Подводя итог, это имеет значение, если вы используете структуру dim3. Я бы понял, где была определена конфигурация потоков, а шаблон доступа 1D, 2D и 3D зависит от того, как вы интерпретируете свои данные, а также как вы обращаетесь к ним с помощью 1D, 2D и 3D блоков потоков.

Смежные вопросы