Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 11 лет назад пользователемИнга Шуринова
1 Половинкин А.Н.
2 Постановка задачи Алгоритм вычисления функции axpy на GPU Программная реализация
3 y := alpha*x + y x, y – векторы размерность – n alpha – скаляр
4 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
5 axpy.h – содержит определения (через define) размера блока и размеров матриц axpy_gold.cpp computeGold axpy.cu main randomInit printDiff runAxpy axpy_kernel.cu axpy (kernel)
6 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);
7 инициализируем векторы 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) );
8 создаем и инициализируем таймер unsigned int timer = 0; CUT_SAFE_CALL(cutCreateTimer(&timer)); CUT_SAFE_CALL(cutStartTimer(timer)); определяем конфигурацию выполнения ядра (размер решетки блоков потоков и блока потоков) dim3 threads(BLOCK_SIZE); dim3 grid(n / threads.x); запускаем ядро копируем вычисленный вектор y с устройства на хост
9 останавливаем таймер, выводим время вычислений, освобождаем ресурсы таймера 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);
10 сравниваем результат, полученный на 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); освобождаем память
11 __global__ void axpy( int n, float alpha, float* x, float* y) вычисляем координату текущего блока потоков и сохраняем её в переменную bid int bid = blockIdx.x вычисляем координату текущего потока в блоке потоков и сохраняем её в переменную tid вычисляем индекс элемента в исходном массиве, который будет обрабатываться текущим потоком int index = bid * BLOCK_SIZE + tid
12 вычисляем значение элемента массива, обрабатываемого текущим потоком y[index] = alpha * x[index] + y[index]
13 Nvidia CUDA Programming Guide Многочисленные курсы по CUDA: (на русском языке)
14 ?
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.