Меня беспокоит следующее.более низкая занятость - лучшая производительность
Запуск того же ядра с двумя разными устройствами, один с возможностью вычисления 1.3, а другой с возможностью вычисления 2.0, я получаю лучшую производительность с большим количеством потоков на блок (с высоким уровнем занятости) в 1.3, но наоборот в 2.0. Пик производительности для 2.0, по-видимому, составляет 16 потоков на блок, а занятость 17%. Что-то меньшее или что-то большее, чем эта точка, имеет худшую производительность.
Поскольку, скорее всего, причиной этого является природа самого ядра здесь.
__global__ void
kernel_CalculateRFCH (int xstart, int ystart, int xsize,
int ysize, int imxsize, int imysize, int *test, int *dev_binIm, int *per_block_results)
{
int x2, y2, bin, bin2;
__shared__ int s_pixels[blockDim.x*blockDim.y]; //this wouldn't compile in reailty
int tx = threadIdx.x;
int ty = threadIdx.y;
int tidy = threadIdx.y + blockIdx.y * blockDim.y;
int tidx = threadIdx.x + blockIdx.x * blockDim.x;
if (xstart + xsize > imxsize)
xsize = imxsize - xstart;
if (ystart + ysize > imysize)
ysize = imysize - ystart;
s_pixels[tx * blockDim.y + ty] = 0;
if (tidy >= ystart && tidy < ysize + ystart && tidx >= xstart && tidx < xsize + xstart)
{
bin = dev_binIm[tidx + tidy * imxsize];
if (bin >= 0)
{
x2 = tidx;
y2 = tidy;
while (y2 < ystart + ysize)
{
if (x2 >= xstart + xsize || x2 - tidx > 10)
{
x2 = xstart;
y2++;
if (tidx - x2 > 10)
x2 = tidx - 10;
if (y2 - tidy > 10)
{
y2 = ystart + ysize;
break;
}
if (y2 >= ystart + ysize)
break;
}
bin2 = dev_binIm[x2 + y2 * imxsize];
if (bin2 >= 0)
{
test[(tidx + tidy * imxsize) * 221 + s_pixels[tx * blockDim.y + ty]] = bin + bin2 * 80;
s_pixels[tx * blockDim.y + ty]++;
}
x2++;
}
}
}
for (int offset = (blockDim.x * blockDim.y)/2; offset > 0; offset >>= 1)
{
if ((tx * blockDim.y + ty) < offset)
{
s_pixels[tx * blockDim.y + ty] += s_pixels[tx * blockDim.y + ty + offset];
}
__syncthreads();
}
if (tx * blockDim.y + ty == 0)
{
per_block_results[blockIdx.x * gridDim.y + blockIdx.y] = s_pixels[0];
}
}
Я пользуюсь 2-D резьбой.
ptxas информация: Компиляция функции ввода '_Z20kernel_CalculateRFCHiiiiiiPiS_' для '' sm_10 ptxas информация: Используется 16 регистров, 128 байт SMEM, 8 байт cmem [1] .
16 регистров отображаются в каждом случае на каждом устройстве.
Любые идеи, почему это может происходить, были бы очень поучительными.
Знаете ли вы о работе [Василия Волкова] (http://www.cs.berkeley.edu/~volkov/)? Название вашего вопроса очень напоминает его презентацию «[более высокая производительность при более низкой занятости] (http://www.cs.berkeley.edu/~volkov/volkov10-GTC.pdf)». – tera
Потоки на блок являются фактором определения занятости, но нет прямого отношения, так что увеличение количества потоков на блок увеличивает занятость (и, как вы обнаружили, нет прямой зависимости между занятостью и производительностью). Используйте [Калькулятор занятости] (http://developer.download.nvidia.com/compute/cuda/CUDA_Occupancy_calculator.xls), чтобы узнать о занятости вашего ядра. – tera
Наконец, 16 потоков на блок слишком низки, так как потоки запланированы в _warps_ из 32 потоков. Таким образом, использование только 16 потоков использует только половину доступных ресурсов (возможно, даже меньше по другим причинам, хорошие размеры блоков часто составляют 64,256 потоков на блок). Вы уверены, что не переменили аргументы «потоки на блок» и «количество блоков»? – tera