Половинкин А.Н.. Постановка задачи Алгоритм вычисления функции axpy на GPU Программная реализация.

Презентация:



Advertisements
Похожие презентации
Половинкин А.Н.. Постановка задачи Алгоритм умножения матриц на GPU Программная реализация.
Advertisements

Технологии высокопроизводительных вычислений на GPU и гибридных вычислительных системах Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Томский.
Половинкин А.Н.. Вычисления общего назначения на GPU Архитектура GPU Программная модель выполнения на CUDA Программирование с использованием CUDA Настольная.
Многопроцессорные системы (продолжение). Графические ускорители. Использование графических ускорителей.
Лихогруд Николай Задание. Постановка.
Структура ПО CUDA Приложения, использующие возможности CUDA для параллельной обработки данных, взаимодействуют с GPU через несколько разных программных.
Анатолий Свириденков (сodedgers.com) Блог:
1. a=? b=? c=? {int a, b, c; a=(b=2+3)/2 - 4+(c=5%2); printf("%d %d %d \n", a, b, c); }
Часть I: Введение в CUDA Александр Межов Ассистент кафедры Информатики 30 сентября 2011 Кафедра Информатики.
Двумерные динамические массивы. Двумерный массив - это одномерный массив, элементами которого являются одномерные массивы. Другими словами, это набор.
1. a=? b=? c=? {int a, b, c; a=(b=2+3)/2 - 4+(c=5%2); printf("%d %d %d \n", a, b, c); }
Лекция 14 Динамические данные. Виды памяти Существует три вида памяти: статическая, стековая и динамическая. Статическая память выделяется еще до начала.
Иерархия памяти CUDA. Глобальная память. Параллельные решения задач умножения матриц и решения СЛАУ. zЛекторы: yБоресков А.В. (ВМиК МГУ)Боресков А.В. (ВМиК.
Стадник Е. Г. ФПМИ НГТУ Руководитель: Городничев М.А., м.н.с. ИВМ и МГ СО РАН.
Многопоточное программирование в OpenMP Киреев Сергей ИВМиМГ.
Разработка на CUDA с использованием Thrust Михаил Смирнов.
Архитектура и программирование массивно-параллельных вычислительных систем zЛекторы: yБоресков А.В. (ВМиК МГУ)Боресков А.В. (ВМиК МГУ) yХарламов А. (NVidia)Харламов.
Лекторы: Боресков А.В. (ВМиК МГУ) Харламов А.А. (NVidia) CUDA Stream. Иерархия памяти в CUDA. Глобальная память.
1 Лекция 3 Разработка алгоритмов и программ сверху вниз.
OpenMPOpenMPРазличие между тредами и процессами ПроцессыТреды.
Транксрипт:

Половинкин А.Н.

Постановка задачи Алгоритм вычисления функции axpy на GPU Программная реализация

y := alpha*x + y x, y – векторы размерность – n alpha – скаляр

BLOCK_SIZE... THREAD BLOCK 1 THREAD BLOCK 2 THREAD BLOCK K n Каждый блок потоков занимается вычислением одного подвектора y sub,i вектора y Каждый поток внутри блока потоков занимается вычислением одного элемента подвектора y sub,i BLOCK_SIZE THREAD BLOCK i... y sub,i

axpy.h – содержит определения (через define) размера блока и размеров матриц axpy_gold.cpp computeGold axpy.cu main randomInit printDiff runAxpy axpy_kernel.cu axpy (kernel)

void runAxpy(int argc, char** argv) инициализируем устройство (device) CUT_DEVICE_INIT(argc, argv); выделяем память на хосте для хранения векторов x и y unsigned int mem_size = sizeof(float) * n; float* h_x = (float*)malloc(mem_size); float* h_y = (float*)malloc(mem_size);

инициализируем векторы x и y случайными значениями randomInit(h_x, n); randomInit(h_y, n); выделяем память под векторы x и y на устройстве, копируем данные с хоста на устройство float* d_x; CUDA_SAFE_CALL(cudaMalloc((void**)&d_x, mem_size)); float* d_y; CUDA_SAFE_CALL(cudaMalloc((void**)&d_y, mem_size)); CUDA_SAFE_CALL(cudaMemcpy(d_x, h_x, mem_size, cudaMemcpyHostToDevice) ); CUDA_SAFE_CALL(cudaMemcpy(d_y, h_y, mem_size, cudaMemcpyHostToDevice) );

создаем и инициализируем таймер unsigned int timer = 0; CUT_SAFE_CALL(cutCreateTimer(&timer)); CUT_SAFE_CALL(cutStartTimer(timer)); определяем конфигурацию выполнения ядра (размер решетки блоков потоков и блока потоков) dim3 threads(BLOCK_SIZE); dim3 grid(n / threads.x); запускаем ядро копируем вычисленный вектор y с устройства на хост

останавливаем таймер, выводим время вычислений, освобождаем ресурсы таймера CUT_SAFE_CALL(cutStopTimer(timer)); printf("Processing time: %f (ms) \n", cutGetTimerValue(timer)); CUT_SAFE_CALL(cutDeleteTimer(timer)); вычисляем то же самое произведение на CPU float* reference = (float*) malloc(mem_size); computeGold(reference, alpha, h_x, h_y, n);

сравниваем результат, полученный на GPU, с результатом, полученным на CPU (по евклидовой норме) CUTBoolean res = cutCompareL2fe(reference, h_y, n, 1e-6f); printf("Test %s \n", (1 == res) ? "PASSED" : "FAILED"); if (res!=1) printDiff(reference, h_y, n); освобождаем память

__global__ void axpy( int n, float alpha, float* x, float* y) вычисляем координату текущего блока потоков и сохраняем её в переменную bid int bid = blockIdx.x вычисляем координату текущего потока в блоке потоков и сохраняем её в переменную tid вычисляем индекс элемента в исходном массиве, который будет обрабатываться текущим потоком int index = bid * BLOCK_SIZE + tid

вычисляем значение элемента массива, обрабатываемого текущим потоком y[index] = alpha * x[index] + y[index]

Nvidia CUDA Programming Guide Многочисленные курсы по CUDA: (на русском языке)

?