Программирование высокопараллельного процессора NVIDIA CUDA (2): упражнения по параллельному выполнению данных

Программирование высокопараллельного процессора NVIDIA CUDA (2): упражнения по параллельному выполнению данных

  1. Если один SM устройства CUDA может содержать 1536 потоков и 4 блока потоков, какая из следующих конфигураций блоков потоков может содержать наибольшее количество потоков в одном SM?
    а) 128 потоков на блок потоков
    б) 256 потоков на блок потоков
    в) 512 потоков на блок потоков
    г) 1024 потоков на блок потоков
    Ответ: в, один SM содержит 3 блока потоков, всего 1536 потоков.

  2. При сложении векторов, если длина вектора равна 2000, каждый поток создает элемент вывода, а каждый блок потока содержит 512 потоков. Сколько потоков в сетке?
    а. 2000 г.
    б. 2024 г.
    в
    . 2048 г. г. 2096 г.
    Ответ: в, ceil (2000/512) = 2048

  3. В предыдущем вопросе, какое количество деформаций приведет к разнообразию ветвей из-за проверки границ длины вектора?
    а. 1
    б. 2
    в. 3
    г. 6
    Ответ: а. Некоторые потоки в последнем варпе удовлетворяют условию если, а некоторые нет В варпе будет два пути потока управления, то есть разнесение ветвей.

  4. Напишите функцию обработки изображения с размером 400x900, используйте один поток для обработки одного пикселя, а блок потоков представляет собой квадрат, как задать размеры блоков сетки и потоков, чтобы каждый блок потоков содержал как можно больше потоков?
    Ответ: Размер сетки 13x29, а размер блока резьбы 32x32.

  5. В настройке предыдущего вопроса, сколько будет сгенерировано бездействующих потоков?
    Ответ: 16 928+28 416-16*28 = 26 048.

  6. 8 потоков образуют блок потоков, и 8 потоков выполняют один и тот же фрагмент кода.Время, необходимое для каждого потока: 2.0, 2.3, 3.0, 2.8, 2.4, 1.9, 2.6 и 2.9, а остальное время ожидания чтобы достичь точки синхронизации. Какой процент от общего времени выполнения стека времени был потрачен на все потоки, ожидающие точки синхронизации?
    Ответ: Максимальное время выполнения 3,0 с, а остальные потоки должны ждать до 3,0 с.Все времена выполнения вычесть из 3, сложить и разделить на общее время выполнения.

  7. Когда программист CUDA говорит, что в функции ядра есть только 32 потока на блок потока, инструкцию __syncthreads() можно опустить, верно?
    Ответ: На первый взгляд это так, потому что потоки в варпе выполняются синхронно. Но это может вызвать проблемы, лучше всего добавить его.
    Ссылаться на

  8. Я собираюсь выполнить умножение блочной матрицы для матрицы 1024x1024, используя размер сетки 32x32, с 512 потоками на блок потоков, по одному элементу на поток, как вы думаете, я смогу это сделать?
    Ответ: Не могу, всего есть потоки 1024х512, а есть числа 1024х1024, каждый поток должен обрабатывать два элемента, а один не может.

  9. Следующая функция ядра используется для обработки блочной матрицы.Для обработки блока начинающий программист CUDA написал следующую функцию ядра для транспонирования каждой блочной матрицы. Размер блока равен BLOCK_WIDTH*BLOCK_WIDTH, каждое измерение матрицы A кратно BLOCK_WIDTH, значение BLOCK_WIDTH равно 1~20, код ядра выглядит следующим образом:

dim3 blockDim(BLOCK_WIDTH,BLOCK_WIDTH);
dim3 gridDim(A_width/blockDim.x,A_height/blockDim.y);
BlockTranspose<<<gridDim, blockDim>>>(A, A_width, A_height);
__global__ void
BlockTranspose(float* A_elements, int A_width, int A_height)
{
    
    
	__shared__ float blockA[BLOCK_WIDTH][BLOCK_WIDTH];
	int baseIdx=blockIdx.x * BLOCK_SIZE + threadIdx.x;
	baseIdx += (blockIdx.y * BLOCK_SIZE + threadIdx.y) * A_width;
	blockA[threadIdx.y][threadIdx.x]=A_elements[baseIdx];
	A_elements[baseIdx]=blockA[threadIdx.x][threadIdx.y];
}

А. Какое значение BLOCK_WIDTH может гарантировать правильное выполнение функции ядра на устройстве?
Поскольку __syncthreads() не используется, каждый блок потока имеет самое большее количество потоков warpsize, поэтому BLOCK_WIDTH должен быть равен 1~5. Все, что больше 5, работать не будет.
б. Если его невозможно выполнить для всех значений BLOCK_WIDTH, измените код, чтобы разрешить выполнение.

существовать

__shared__ float blockA[BLOCK_WIDTH][BLOCK_WIDTH];

и

blockA[threadIdx.y][threadIdx.x]=A_elements[baseIdx]

Добавьте __syncthreads() между ними.

ссылка

Supongo que te gusta

Origin blog.csdn.net/weixin_45773137/article/details/124897806
Recomendado
Clasificación