SlideShare une entreprise Scribd logo
1  sur  65
Параллельное программирование На современных видеокартах(GPGPU) Алексей Тутубалинwww.gpgpu.rulexa@lexa.ru
План встречи
Параллельные вычисления: зачем? ,[object Object]
Рост производительности CPU сильно замедлился,[object Object]
Параллельные вычисления Как? Одновременное исполнение независимых вычислений на разных процессорах с последующей синхронизацией Проблемы: Правило Амдала: ускорение=P – доля программы, которую можно распараллелить, N – число потоков исполнения Слишком маленькие независимые блоки много затрат на синхронизацию Сложно программировать (много объектов, синхронизация, критические секции)
Параллельные системы
Высокая производительность: объективные проблемы Задержки (Latency) Часто определяют производительностьПример: Умножение матриц наивным способом - медленный доступ «по столбцам»: особенности памяти (и кэшей, если не повезло) Синхронизация: всегда непроизводительное ожидание Скорость чтения/записи в память (Bandwidth) Часто определяет производительностьSSE на Core i7:  две векторные  (16 байт) операции  на такт(96  байт/такт), скорость доступа к памяти порядка 6 байт/такт (или 1-1.5 байта на ядро) Нужна быстрая память, кэши частично спасают Нужно повышение сложности: больше операций над данными в регистрах. Распределенные системы: линейный рост bandwidth Арифметическая интенсивность (операций/единица данных) a = b+c: 1 операция, 2 чтения, 1 запись Распараллеливание может стать бессмысленным, весь выигрыш будет съеден пересылками Чтобы был выигрыш от параллельности, алгоритмы должны быть либо сложнее O(n),либо для O(n) – константапри O – большая.
Вычисления на GPU: предпосылки
«Старые видеокарты» (2003-2006) Специализация под 3D-графику (отрисовка2D-проекции сцены) Фиксированные стадии обработки (вершины-геометрия-пиксели) С 2001 – программируемые шейдеры (GeForce3, OpenGL 1.5) Высокая производительность за счет: Архитектуры, сделанной ровно под одну задачу Высокой скорости линейного чтения памяти Отсутствия синхронизации внутри стадии обработки
2001-2006: «Многообещающие результаты» ~3000 научных публикацийС общим смыслом «вот на следующих поколениях оборудования все будет хорошо...» Первые средства разработки для не-графики: Brook, Sh Результаты: Ускорение линейной алгебры в разы (относительно CPU), но single precision Сортировка: ускорение в разы, GPUTeraSortвыиграла Sort Benchmark 2006г Промышленное использование: Обработка сигналов Обработка цифрового кино (поток 200-500Mb/sec)
Проблемы начального этапа Неудобная парадигма «Потоковых вычислений» (Stream Computing): «микропрограммы» (шейдеры) – обработка одного элемента входного потока Никакого взаимодействия между потоками Многие задачи очень неудобно программировать Только одинарная точность вычислений Неудобство средств разработки
2006: NVidia CUDA и G80 Compute Unified Device Architecture Принципиально новая (для GPU) архитектура Взаимодействие между потоками вычислений Произвольный код вместо шейдеров Иерархическая структура памяти 345 GFLOP/s (single), 87Gb/sec memory bandwidth Средства программирования общего назначения (CUDA): Вычислительный код на языке «С» Компактная архитектура запуска вычислителей Много готовых вычислительных примеров Готовые библиотеки BLAS и FFT в поставке Прекрасная поддержка разработчиков и университетов 2007: NVidia Tesla – «Supercomputer on Desktop» - «видеокарты без видеовыхода», только вычисления
2006: интерес других производителей ATI (AMD): Инициатива Close-To-Metal: публикация спецификаций кода, надежда на отказ от OpenGL и появление нормальных компиляторов FireStream – первый ускоритель для вычислений а не видеокарта Остаются в парадигме потоковых вычислений Cell (IBM-Sony-Toshiba) 8 ядер с локальной памятью (256кб на ядро) Быстрая внешняя шина (25Gb/sec) 230 GFLOP/s single, 15-20GFLOP/s double PlayStation 3 и плата в серверы
2007-2008: быстрое взросление >2000 публикаций про использование CUDA Топовые конференции (Supercomputing) Хорошие готовые библиотеки Новое оборудование: Поддержка двойной точности у всех NVidia:	G200 – 800 GFLOP/s single, 100 – double,  ATI HD4870:  1000/240 GFLOP/s single/double, но все еще потоковое программирование IBM PowerXCell: ~200/100 GFLOP/s
Ускорение приложений на CUDA 2008 г.: NVidia 8800GTX в сравнении с AMD Opteron 248 (2.2GHz, 2 ядра)
Современный этап: оборудование Видеокарты: ATI R800 2.7TFLOP/s single, 500 GFLOP/s double Поддержка OpenCL (не только потоковые вычисления) NVidia GF100 (Fermi): Tesla 1.2 TFLOP/s single, 600 GFLOP/s double Geforce GTX 480: 1.3 TFLOP/s single, ~180 GFLOP/s double Для сравнения, топовые x86 CPU: 80-110GFLOP/s (double) GPU-кластеры Промышленные решения (Cray, IBM, Т-платформы) Суперкомпьютеры: Nebulae - №2 в Supercomputer Top500 по реальной производительности, №1 по пиковой.
Современный этап: программы Стандарт  OpenCL (лето-осень 2009): переносимые GPU-программы Для пользователяускорение multimedia, обработка изображений и видео, 3D-моделирование, инженерные программы... Для программиста много готовых библиотек: линейная алгебра, обработка сигналов, computer vision Для ученого: поддержка в расчетных программах Общего назначения: Matlab, Mathematica Специализированные пакеты: проектирование, компьютерная химия, компьютерная биология, молекулярная динамика
Современный этап: производительность
Наглядная агитация 4xTesla  == Cray XT4  на задачах молекулярной биологии (AMBER11)(слайд с NVidia GPU Technology conference, 22 сентября 2010)
NVidia CUDACompute Unified Device Architecture Общий обзор «сверху вниз» Как устроено оборудование И как это отражается в логической структуре программ Минимальные примеры программ Некоторые тонкие моменты Обзор средств программиста и дополнительных библиотек Нет задачи и возможности заменить чтение документации и самостоятельные упражнения
Общая схема исполнения программ Все стадии независимы, одновременно можно: Передавать в видеопамять Считать (другие данные) Передавать из видеопамяти
Архитектура G80 До 16 одинаковых мультипроцессоровна чипе Общая глобальная память (R/W): медленная и много (до 1.5Gb) Общая константная память (RO): быстрая и мало Общий планировщик потоков (блоками) Общий исполняемый код на вечь чип G80Streaming Multiprocessor (SM) ,[object Object]
2 специальных процессора (SFU) для сложных функций: 32 потока за 16 тактов, SIMD
Один диспетчер команд
до 768 потоков на одном SM в «одновременном» режиме
 потоки объединяются в пачки по 32 потока (warp), которые исполняются SIMD
 16 kb разделяемой памяти (shared memory)
 8192 32-битных регистраНа 2 SM – один блок обработки текстур с текстурным кэшем и блоком аппаратной интерполяции … TPC TPC TPC TPC TPC TPC Streaming Multiprocessor Texture Processor Cluster Instruction L1 Data L1 Instruction Fetch/Dispatch SM Shared Memory TEX SP SP SP SP SM SFU SFU SP SP SP SP
Texture Texture Texture Texture Texture Texture Texture Texture Texture Host Input Assembler Thread Execution Manager Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Load/store Load/store Load/store Load/store Load/store Load/store Global Memory G80: общая схема
Логическая организация программ Десятки тысяч – миллионы независимых потоков в программе Поток – обрабатывает часть входных данных Потоки объединены в блоки Общая shared memory Синхронизация Блоки объединены в grid Синхронизации нет Grid of Thread Blocks
Логическая организация (2) Блок исполняется на одном мультипроцессоре Разные блоки – на разных Порядок не определен Может быть несколько блоков на SM одновременно Нумерация потоков в блоке: 1D, 2D или 3D Нумерация блоков: 1D,2D Каждый поток знает свое положение в сетке и блоке
Иерархия памяти
Параметры SM – не догма G92: 16384регистров, до 1024 потоков  на SM GF100 (Fermi) 32768 регистров и 32/48 процессоров на SM  1536 потоков (48 warp) на SM 64kb shared memory+L1-cache (16/48 или 48/16 shared/cache) Другие параметры другой оптимальный код Другие улучшения Атомарные операции (G86, G92) Поддержка двойной точности (G200, GF100)
Пример: cложение двух векторов Код GPU: складываем два элемента: __global__ void VecAdd(float* A,float* B, float* C, int N) {   int i = blockDim.x * blockIdx.x + threadIdx.x;   if (i < N)     C[i] = A[i]+B[i]; } threadIdx – предопределенная переменная (3-компонентный вектор) – номер потока в блоке blockDim – размерность одного блока (3D) blockIdx – номер блока в сетке (2D)
код на CPU // аллоцируем память на GPU size_t size = N * sizeof(float); cudaMalloc((void**)&d_A, size); cudaMalloc((void**)&d_B, size); cudaMalloc((void**)&d_C, size); // копируем данные на GPU cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);  cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice); // запускаем kernel на GPU (1D сетка и блок): int Nthreads = 256; int Nblocks = (N+Nthreads-1)/Nthreads; VecAdd<<<Nblocks,Nthreads>>>(d_A, d_B, d_C, N); // получаем результаты с GPU cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
CUDA:С/C++ с небольшими изменениями Спецификаторы типа функции: __global__- GPU, может быть вызвана с CPU (с параметрами) __device__ - GPU, вызывается из __global__ __host__ - CPUРекурсия и указатели на функции: только Fermi (GF100)  Спецификаторы местоположения переменной __device__ - глобальная память, R/W __constant__ - константная память, R/O __shared__ - shared memory, R/W, локальна в блоке Автоматические переменные – могут быть в регистрах, если известен размер и регистров достаточно. Иначе – local memory, т.е. живут в медленной глобальной памяти
Типы данных и переменные Скалярные:char, short, int, long,longlong, float, double (и беззнаковые для целых) Векторные:  <=32 бит/компонент – до 4 элементов (uchar2,float4) 64 бита – 2 элемента (double2, longlong2) Векторных операций НЕТ: c.x=a.x+b.x работает,  c=a+b - нет dim3 – тип для задания размера сетки блоков Встроенные переменные: gridDim, blockDim– размер сетки и блока (dim3) blockIdx, threadIdx– номер блока и потока (dim3) warpSize – ширина SIMD (пока всегда 32)
Двумерные блоки например, для двумерных моделей На CPU: dim3 blockSize(16, 16); // некратным размером сетки пренебрегаем...  dim3 gridSize(width/blockSize.x,	height/blockSize.y); myKernel<<<gridSize,blockSize>>>(…..) На GPU uint x = blockIdx.x*blockDim.x+threadIdx.x; uint y = blockIdx.y*blockDim.y +threadIdx.y;
Синхронизация, атомарные операции Глобальная синхронизация всех блоков – завершение kernel __syncthreads() – синхронизация потоков блока Атомарные сложения, вычитания и т.п. (atomicAdd() и т.д.) -  G86+ Shared или Global memory (G86 – только global) Атомарное исполнение Медленные
Скалярное произведение Накапливаем частные произведенияпо потокам: __global__ result; shared__ float psum[NTHREADS]; psum[threadIdx.x] = 0; for(j=0;j<K*NTHREADS;j+=NTHREADS) psum[threadIdx.x] += A[base+j]*B[base+j]; __syncthreads(); // Складываем для блока if(threadIdx.x == 0) { 	for(j=1;j<blockDim.x;j++) psum[0]+=psum[j]; 	// синхронизации не надо!! 0-йthread atomicAdd(&result,psum[0]); }
Тонкости Оптимальный доступ к глобальной памяти Особенности доступа к shared memory Условные операции Распределение блоков по процессорам
Доступ к глобальной памяти Сложение векторов, 16 сложений на thread: ___________________________________________________ int j,base = (blockDim.x*blockIdx.x+threadIdx.x)*16; for(j=0;j<16;j++) C[base+j] = A[base+j] + B[base+j] Thread0:  A[0], A[1] Thread1: A[16], A[17] Весь Warp обращается c «размахом» в 512 слов ______________________________________________________ int j,base = (blockDim.x*blockIdx.x)*16+threadIdx.x; for(j=0;j<blockDim.x*16;j+=blockDim.x) C[base+j] = A[base+j] + B[base+j] Thread0:  A[0], A[blockDim.x]... Thread1: A[1], A[blockDim.x+1].... Весь Warp обращается к соседним словам Второй вариант – coalesced access: доступ к соседним адресам
Доступ к глобальной памяти - 2 Прямые рекомендации из Programming Guide: Оптимально, когда все потоки одного (полу)-warp*обращаются к одному 128-байтному сегменту Для 16-байтных элементов (вектор) – два подряд 128-байтных сегмента. В правильном порядке – k-йthread к k-му элементу в сегменте. Идеальная ситуация: Array[base + treadIdx.x]Array[base] – выровнен на 128 байт
Разделяемая память Разделена на банки  16 банков на G80-G200, 32 на GF100 Interleave 4 байта Два потока в 1 банк =>конфликт, каждый конфликт – 4 такта ожидания Оптимальный доступ array[threadIdx]
Нет конфликта банков Bank 0 Thread 0 Bank 0 Thread 0 Bank 1 Thread 1 Bank 1 Thread 1 Bank 2 Thread 2 Bank 2 Thread 2 Bank 3 Thread 3 Bank 3 Thread 3 Bank 4 Thread 4 Bank 4 Thread 4 Bank 5 Thread 5 Bank 5 Thread 5 Bank 6 Thread 6 Bank 6 Thread 6 Bank 7 Thread 7 Bank 7 Thread 7 Bank 15 Thread 15 Bank 15 Thread 15
Конфликт банков Bank 0 Bank 1 Thread 0 Bank 2 Thread 1 Bank 3 Thread 2 Bank 4 Thread 3 Bank 5 Thread 4 Bank 6 Bank 7 Thread 8 Thread 9 Bank 15 Thread 10 Thread 11 GF100: несколько чтений разных потоков по одному адресу (не банку) – не приводят к конфликту (broadcast данных)
Условные операции SIMD  поэтому если в одном warp разные ветки if, их исполнение будет последовательным: if (threadIdx.x %2) 	{ четные ветки стоят, нечетные работают} else 	{ четные работают, нечетные стоят }
Распределение блоков по SM Не меньше одного блока т.е. блок должен пролезать по ресурсам: Общее число потоковв блоке < лимита оборудования Требуемое количество shared memory< лимита Общее количество регистров (регистров на поток * число потоков) < лимита  Несколько блоков на SM – если достаточно ресурсов (регистров, shared memory, потоков) G80-G200 – передача параметров в shared mem, 2 X 8192 – не влезет в 16 килобайт
Загрузка SM (occupancy) Отношение числа работающих warps к из возможному количеству В общем случае, к 100% надо стремиться: Прячется латентность доступа к памяти Но мало регистров (G92 – 16 регистров/thread) Альтернативный подход: Мало потоков (128-192-256 на SM) Зато много регистров на поток Полезно для блочных алгоритмов Подробнее: Volkov, V. 2010. Use registers and multiple outputs per thread on GPUhttp://www.cs.berkeley.edu/~volkov/volkov10-PMAA.pdf
Разное Целая арифметика: G80-G200: 24-бита – быстрая, 32 бита – медленная GF100 – 32 бита – быстрая, 24 бита - медленная Текстуры: 1-2-3D-массивы Кэшируются, кэш локален по координатам (эффективное кэширование по столбцам, при последовательном доступе – медленнее global memory) Аппаратная интерполяция
Продолжение..... Документация NvidiaОчень хорошая!http://developer.nvidia.com/object/cuda_download.html CUDA Programming Guide CUDA Reference Guide CUDA Best Practices Guide Примеры SDK и документация к нимhttp://developer.download.nvidia.com/compute/cuda/sdk/website/samples.html Форумы Nvidiahttp://forums.nvidia.com/index.php?showforum=62
Программные средства CUDA Toolkit – компилятор + библиотеки Интегрируется с Visual C++ (добавление правил компиляции для .cu) Отладчик – gdb (командная строка) Visual Profiler – не на уровне отдельных строк кода Parallel Nsight Пошаговая отладка Глобальный профайлинг Standard (бесплатная) и Professional (бесплатная для ВУЗов) версии CUDA-x86 Был эмулятор, но в Cuda 3.x удален PGI обещает компилятор
Подробности компиляции float4 me = gx[gtid]; me.x += me.y * me.z; C/C++ CUDA Application CPU-code компилируется родным компилятором PTX – неоптимизированный ассемблер, дальнейшие варианты: ,[object Object]
Компиляция в внешний .cubin-файл и загрузка на runtimeФинальную компиляцию  реальные коды делает драйвер видеокарты NVCC CPU Code PTX Code Virtual Physical PTX to Target Compiler  G80    …     GPU  Target code
Два API CUDA C API:  реализуется внешней библиотекой cudart Высокоуровневое, более удобное удобная поддержка нескольких контекстов (например для использования в многопоточных программах) CUDA Driver API:  Аналогично по возможностям Не требует дополнительных библиотек Больше работы программисту
Альтернативы CUDA OpenCL CAL/IL (Compute Abstraction Layer/Intermediate Language) Только видеокарты ATI Потоковое программирование Плохо поддерживается DirectX 11 (DirectCompute) Только Windows
OpenCL Многоплатформенный стандарт Необычайно похож на CUDA Driver API Детали: Язык C для kernels, другие ключевые слова Компиляция из исходных текстов на ходу («в драйвере») Уже две версии (1.0 и 1.1) Нестандартная конфигурация поддерживается через «расширения»
Сложение векторов Код GPU: __kernel void VectorAdd(__global const float* a,__global const float* b,__global float* c, int N) { 	int iGID = get_global_id(0); 	if (iGID < N) 		c[iGID] = a[iGID] + b[iGID]; }
Код CPU // Создаем контекст GPU (до того был поиск устройств...) Context = clCreateContext(0, 1, &cdDevice, NULL, NULL, &ciErr1); // и очередь команд CommandQueue = clCreateCommandQueue(Context, cdDevice, 0, &ciErr1); // Аллоцируем массив(ы) на GPU cmDevSrcA = clCreateBuffer(Context, CL_MEM_READ_ONLY, sizeof(cl_float) * szGlobalWorkSize, NULL, &ciErr1); …. И еще два аллоцирования .... // Создаем (компилируем) программу из исходных текстов cpProgram = clCreateProgramWithSource(Context, 1, (const char **)&cSourceCL, &szKernelLength, &ciErr1); // создаем из нее kernel ckKernel = clCreateKernel(cpProgram, "VectorAdd", &ciErr1); // задаем ему аргумент(ы) clSetKernelArg(ckKernel, 0, sizeof(cl_mem), (void*)&cmDevSrcA); .... И еще три аргумента ...... // В очередь команд помещаем копирование данных и запуск kernel, все асинхронно clEnqueueWriteBuffer(CommandQueue, cmDevSrcA, CL_FALSE, 0, sizeof(cl_float) * szGlobalWorkSize, srcA, 0, NULL, NULL); .... И еще одно копирование.... clEnqueueNDRangeKernel(CommandQueue, ckKernel, 1, NULL, &szGlobalWorkSize, &szLocalWorkSize, 0, NULL, NULL); // В очередь команд помещаем синхронное чтение результата clEnqueueReadBuffer(CommandQueue, cmDevDst, CL_TRUE, 0, sizeof(cl_float) * szGlobalWorkSize, dst, 0, NULL, NULL);
CUDA  OpenCL AMD: Porting CUDA to OpenCLhttp://developer.amd.com/zones/OpenCLZone/Pages/portingcudatoopencl.aspx
Переносимость и производительность Переносимыйкод (NVidia, ATI,x86, Cell) Производительность не переносится: Либо используем векторные типы на векторных архитектурах (ATI, Cell) и получаем непереносимый код Либо код получается переносимый и в разы медленнее Перенос CUDA  OpenCL – потеря 20-30%. Компилятор?? CUDA всегда будет впереди т.к. нет этапа согласований с рабочей группой
OpenCL и видеокарты ATI Человеческий интерфейс (в отличие от CAL/IL) HD5870 – производительность примеров SDK -  на уровне GTX280 (в разы ниже ожидаемого) HD4xxx – производительность плохая т.к. нет shared memory (эмуляция через глобальную) Плохая документация (в сравнении с...) Но что делать, если попалось такое оборудование и не хочется ассемблера.....
Почему GPU НАСТОЛЬКО быстрее? ,[object Object]
Обработка сигналов, обработка изображений: десятки раз
Некоторые задачи (молекулярная динамика, N-body): бывают сотни раз,[object Object]

Contenu connexe

Tendances

Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...a15464321646213
 
Виртуалтрединг
ВиртуалтредингВиртуалтрединг
ВиртуалтредингCEE-SEC(R)
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...Mikhail Kurnosov
 
Введение в Deep Learning
Введение в Deep LearningВведение в Deep Learning
Введение в Deep LearningGrigory Sapunov
 
Методы оптимизации вычислений на CPU
Методы оптимизации вычислений на CPUМетоды оптимизации вычислений на CPU
Методы оптимизации вычислений на CPUMSU GML VideoGroup
 
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Mikhail Kurnosov
 
Multiprocessor Programming Intro (lecture 1)
Multiprocessor Programming Intro (lecture 1)Multiprocessor Programming Intro (lecture 1)
Multiprocessor Programming Intro (lecture 1)Dmitry Tsitelov
 
Распределенные мультикластерные вычислительные системы и параллельное мультип...
Распределенные мультикластерные вычислительные системы и параллельное мультип...Распределенные мультикластерные вычислительные системы и параллельное мультип...
Распределенные мультикластерные вычислительные системы и параллельное мультип...Mikhail Kurnosov
 
Технология предметно ориентированного программирования гетерогенных многоядер...
Технология предметно ориентированного программирования гетерогенных многоядер...Технология предметно ориентированного программирования гетерогенных многоядер...
Технология предметно ориентированного программирования гетерогенных многоядер...CEE-SEC(R)
 
Современные архитектуры диалоговых систем / Анатолий Востряков (Segmento)
Современные архитектуры диалоговых систем / Анатолий Востряков (Segmento)Современные архитектуры диалоговых систем / Анатолий Востряков (Segmento)
Современные архитектуры диалоговых систем / Анатолий Востряков (Segmento)Ontico
 
06 vasenin roganov siis_2013
06 vasenin roganov siis_201306 vasenin roganov siis_2013
06 vasenin roganov siis_2013Marina_creautor
 
Введение в архитектуры нейронных сетей / HighLoad++ 2016
Введение в архитектуры нейронных сетей / HighLoad++ 2016Введение в архитектуры нейронных сетей / HighLoad++ 2016
Введение в архитектуры нейронных сетей / HighLoad++ 2016Grigory Sapunov
 
Introduction in CUDA (1-3)
Introduction in CUDA (1-3)Introduction in CUDA (1-3)
Introduction in CUDA (1-3)Alexander Mezhov
 
Программирование на медиапроцессорах Philips Nexperia
Программирование на медиапроцессорах Philips NexperiaПрограммирование на медиапроцессорах Philips Nexperia
Программирование на медиапроцессорах Philips NexperiaMSU GML VideoGroup
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSUlarhat
 
Цифровая микроэлектроника для математиков и программистов 2017
Цифровая микроэлектроника для математиков и программистов 2017Цифровая микроэлектроника для математиков и программистов 2017
Цифровая микроэлектроника для математиков и программистов 2017Anton Moiseev
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Mikhail Kurnosov
 

Tendances (20)

Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
Виртуалтрединг
ВиртуалтредингВиртуалтрединг
Виртуалтрединг
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
 
Введение в Deep Learning
Введение в Deep LearningВведение в Deep Learning
Введение в Deep Learning
 
Efficiency vvv
Efficiency vvvEfficiency vvv
Efficiency vvv
 
Методы оптимизации вычислений на CPU
Методы оптимизации вычислений на CPUМетоды оптимизации вычислений на CPU
Методы оптимизации вычислений на CPU
 
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
 
Multiprocessor Programming Intro (lecture 1)
Multiprocessor Programming Intro (lecture 1)Multiprocessor Programming Intro (lecture 1)
Multiprocessor Programming Intro (lecture 1)
 
Распределенные мультикластерные вычислительные системы и параллельное мультип...
Распределенные мультикластерные вычислительные системы и параллельное мультип...Распределенные мультикластерные вычислительные системы и параллельное мультип...
Распределенные мультикластерные вычислительные системы и параллельное мультип...
 
Технология предметно ориентированного программирования гетерогенных многоядер...
Технология предметно ориентированного программирования гетерогенных многоядер...Технология предметно ориентированного программирования гетерогенных многоядер...
Технология предметно ориентированного программирования гетерогенных многоядер...
 
Современные архитектуры диалоговых систем / Анатолий Востряков (Segmento)
Современные архитектуры диалоговых систем / Анатолий Востряков (Segmento)Современные архитектуры диалоговых систем / Анатолий Востряков (Segmento)
Современные архитектуры диалоговых систем / Анатолий Востряков (Segmento)
 
06 vasenin roganov siis_2013
06 vasenin roganov siis_201306 vasenin roganov siis_2013
06 vasenin roganov siis_2013
 
Введение в архитектуры нейронных сетей / HighLoad++ 2016
Введение в архитектуры нейронных сетей / HighLoad++ 2016Введение в архитектуры нейронных сетей / HighLoad++ 2016
Введение в архитектуры нейронных сетей / HighLoad++ 2016
 
Обзор OpenCL
Обзор OpenCLОбзор OpenCL
Обзор OpenCL
 
Introduction in CUDA (1-3)
Introduction in CUDA (1-3)Introduction in CUDA (1-3)
Introduction in CUDA (1-3)
 
Программирование на медиапроцессорах Philips Nexperia
Программирование на медиапроцессорах Philips NexperiaПрограммирование на медиапроцессорах Philips Nexperia
Программирование на медиапроцессорах Philips Nexperia
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSU
 
Цифровая микроэлектроника для математиков и программистов 2017
Цифровая микроэлектроника для математиков и программистов 2017Цифровая микроэлектроника для математиков и программистов 2017
Цифровая микроэлектроника для математиков и программистов 2017
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)
 
CUDA Best Practices (2-3)
CUDA Best Practices (2-3)CUDA Best Practices (2-3)
CUDA Best Practices (2-3)
 

Similaire à Параллельное программирование на современных видеокартах

Hpc 2.26.03.2013.
Hpc 2.26.03.2013.Hpc 2.26.03.2013.
Hpc 2.26.03.2013.Boris Kizko
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)Smolensk Computer Science Club
 
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Mikhail Kurnosov
 
Работа с Big Data
Работа с Big Data Работа с Big Data
Работа с Big Data MATLAB
 
Лекция 9. Программирование GPU
Лекция 9. Программирование GPUЛекция 9. Программирование GPU
Лекция 9. Программирование GPUMikhail Kurnosov
 
Сервисы Azure для научных исследований
Сервисы Azure для научных исследованийСервисы Azure для научных исследований
Сервисы Azure для научных исследованийMicrosoft
 
Архитектура и программирование на fpga
Архитектура и программирование на fpgaАрхитектура и программирование на fpga
Архитектура и программирование на fpgaMSU GML VideoGroup
 
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAЛекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAMikhail Kurnosov
 
презентация на защиту 06.06
презентация на защиту 06.06презентация на защиту 06.06
презентация на защиту 06.06Boris Kizko
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2Technopark
 
Лекция 2 Разработка программно-аппаратного обеспечения информационных и автом...
Лекция 2 Разработка программно-аппаратного обеспечения информационных и автом...Лекция 2 Разработка программно-аппаратного обеспечения информационных и автом...
Лекция 2 Разработка программно-аппаратного обеспечения информационных и автом...VThn18
 
подготовленная презентация проекта Gpu digital lab от компании аксиома для ко...
подготовленная презентация проекта Gpu digital lab от компании аксиома для ко...подготовленная презентация проекта Gpu digital lab от компании аксиома для ко...
подготовленная презентация проекта Gpu digital lab от компании аксиома для ко...oleg gubanov
 
Гидродинамическое моделирование: возможности оптимизации ИТ-инфраструктуры
Гидродинамическое моделирование: возможности оптимизации ИТ-инфраструктурыГидродинамическое моделирование: возможности оптимизации ИТ-инфраструктуры
Гидродинамическое моделирование: возможности оптимизации ИТ-инфраструктурыVsevolod Shabad
 
DEV Labs 2013. Can C++ Code Effeciency Be Comparable to That of Middle-Level ...
DEV Labs 2013. Can C++ Code Effeciency Be Comparable to That of Middle-Level ...DEV Labs 2013. Can C++ Code Effeciency Be Comparable to That of Middle-Level ...
DEV Labs 2013. Can C++ Code Effeciency Be Comparable to That of Middle-Level ...Alex V. Petrov
 
Суперкомпьютеры сегодня и завтра архитектура, проблемы, перспективы (Андрей С...
Суперкомпьютеры сегодня и завтра архитектура, проблемы, перспективы (Андрей С...Суперкомпьютеры сегодня и завтра архитектура, проблемы, перспективы (Андрей С...
Суперкомпьютеры сегодня и завтра архитектура, проблемы, перспективы (Андрей С...Ontico
 
Технические средства реализации информационных процессов
Технические средства реализации информационных процессовТехнические средства реализации информационных процессов
Технические средства реализации информационных процессовstudent_SSGA
 

Similaire à Параллельное программирование на современных видеокартах (20)

Hpc 2.26.03.2013.
Hpc 2.26.03.2013.Hpc 2.26.03.2013.
Hpc 2.26.03.2013.
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)
 
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
 
Работа с Big Data
Работа с Big Data Работа с Big Data
Работа с Big Data
 
Лекция 9. Программирование GPU
Лекция 9. Программирование GPUЛекция 9. Программирование GPU
Лекция 9. Программирование GPU
 
Сервисы Azure для научных исследований
Сервисы Azure для научных исследованийСервисы Azure для научных исследований
Сервисы Azure для научных исследований
 
Cuda, OpenCL
Cuda, OpenCLCuda, OpenCL
Cuda, OpenCL
 
Архитектура и программирование на fpga
Архитектура и программирование на fpgaАрхитектура и программирование на fpga
Архитектура и программирование на fpga
 
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAЛекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
 
08 Видеокарты
08 Видеокарты08 Видеокарты
08 Видеокарты
 
презентация на защиту 06.06
презентация на защиту 06.06презентация на защиту 06.06
презентация на защиту 06.06
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2
 
Лекция 2 Разработка программно-аппаратного обеспечения информационных и автом...
Лекция 2 Разработка программно-аппаратного обеспечения информационных и автом...Лекция 2 Разработка программно-аппаратного обеспечения информационных и автом...
Лекция 2 Разработка программно-аппаратного обеспечения информационных и автом...
 
подготовленная презентация проекта Gpu digital lab от компании аксиома для ко...
подготовленная презентация проекта Gpu digital lab от компании аксиома для ко...подготовленная презентация проекта Gpu digital lab от компании аксиома для ко...
подготовленная презентация проекта Gpu digital lab от компании аксиома для ко...
 
Гидродинамическое моделирование: возможности оптимизации ИТ-инфраструктуры
Гидродинамическое моделирование: возможности оптимизации ИТ-инфраструктурыГидродинамическое моделирование: возможности оптимизации ИТ-инфраструктуры
Гидродинамическое моделирование: возможности оптимизации ИТ-инфраструктуры
 
введение в Gpu
введение в Gpuвведение в Gpu
введение в Gpu
 
04.01 gpfix GeoTracker
04.01 gpfix GeoTracker04.01 gpfix GeoTracker
04.01 gpfix GeoTracker
 
DEV Labs 2013. Can C++ Code Effeciency Be Comparable to That of Middle-Level ...
DEV Labs 2013. Can C++ Code Effeciency Be Comparable to That of Middle-Level ...DEV Labs 2013. Can C++ Code Effeciency Be Comparable to That of Middle-Level ...
DEV Labs 2013. Can C++ Code Effeciency Be Comparable to That of Middle-Level ...
 
Суперкомпьютеры сегодня и завтра архитектура, проблемы, перспективы (Андрей С...
Суперкомпьютеры сегодня и завтра архитектура, проблемы, перспективы (Андрей С...Суперкомпьютеры сегодня и завтра архитектура, проблемы, перспективы (Андрей С...
Суперкомпьютеры сегодня и завтра архитектура, проблемы, перспективы (Андрей С...
 
Технические средства реализации информационных процессов
Технические средства реализации информационных процессовТехнические средства реализации информационных процессов
Технические средства реализации информационных процессов
 

Параллельное программирование на современных видеокартах

  • 1. Параллельное программирование На современных видеокартах(GPGPU) Алексей Тутубалинwww.gpgpu.rulexa@lexa.ru
  • 3.
  • 4.
  • 5. Параллельные вычисления Как? Одновременное исполнение независимых вычислений на разных процессорах с последующей синхронизацией Проблемы: Правило Амдала: ускорение=P – доля программы, которую можно распараллелить, N – число потоков исполнения Слишком маленькие независимые блоки много затрат на синхронизацию Сложно программировать (много объектов, синхронизация, критические секции)
  • 7. Высокая производительность: объективные проблемы Задержки (Latency) Часто определяют производительностьПример: Умножение матриц наивным способом - медленный доступ «по столбцам»: особенности памяти (и кэшей, если не повезло) Синхронизация: всегда непроизводительное ожидание Скорость чтения/записи в память (Bandwidth) Часто определяет производительностьSSE на Core i7: две векторные (16 байт) операции на такт(96 байт/такт), скорость доступа к памяти порядка 6 байт/такт (или 1-1.5 байта на ядро) Нужна быстрая память, кэши частично спасают Нужно повышение сложности: больше операций над данными в регистрах. Распределенные системы: линейный рост bandwidth Арифметическая интенсивность (операций/единица данных) a = b+c: 1 операция, 2 чтения, 1 запись Распараллеливание может стать бессмысленным, весь выигрыш будет съеден пересылками Чтобы был выигрыш от параллельности, алгоритмы должны быть либо сложнее O(n),либо для O(n) – константапри O – большая.
  • 8. Вычисления на GPU: предпосылки
  • 9. «Старые видеокарты» (2003-2006) Специализация под 3D-графику (отрисовка2D-проекции сцены) Фиксированные стадии обработки (вершины-геометрия-пиксели) С 2001 – программируемые шейдеры (GeForce3, OpenGL 1.5) Высокая производительность за счет: Архитектуры, сделанной ровно под одну задачу Высокой скорости линейного чтения памяти Отсутствия синхронизации внутри стадии обработки
  • 10. 2001-2006: «Многообещающие результаты» ~3000 научных публикацийС общим смыслом «вот на следующих поколениях оборудования все будет хорошо...» Первые средства разработки для не-графики: Brook, Sh Результаты: Ускорение линейной алгебры в разы (относительно CPU), но single precision Сортировка: ускорение в разы, GPUTeraSortвыиграла Sort Benchmark 2006г Промышленное использование: Обработка сигналов Обработка цифрового кино (поток 200-500Mb/sec)
  • 11. Проблемы начального этапа Неудобная парадигма «Потоковых вычислений» (Stream Computing): «микропрограммы» (шейдеры) – обработка одного элемента входного потока Никакого взаимодействия между потоками Многие задачи очень неудобно программировать Только одинарная точность вычислений Неудобство средств разработки
  • 12. 2006: NVidia CUDA и G80 Compute Unified Device Architecture Принципиально новая (для GPU) архитектура Взаимодействие между потоками вычислений Произвольный код вместо шейдеров Иерархическая структура памяти 345 GFLOP/s (single), 87Gb/sec memory bandwidth Средства программирования общего назначения (CUDA): Вычислительный код на языке «С» Компактная архитектура запуска вычислителей Много готовых вычислительных примеров Готовые библиотеки BLAS и FFT в поставке Прекрасная поддержка разработчиков и университетов 2007: NVidia Tesla – «Supercomputer on Desktop» - «видеокарты без видеовыхода», только вычисления
  • 13. 2006: интерес других производителей ATI (AMD): Инициатива Close-To-Metal: публикация спецификаций кода, надежда на отказ от OpenGL и появление нормальных компиляторов FireStream – первый ускоритель для вычислений а не видеокарта Остаются в парадигме потоковых вычислений Cell (IBM-Sony-Toshiba) 8 ядер с локальной памятью (256кб на ядро) Быстрая внешняя шина (25Gb/sec) 230 GFLOP/s single, 15-20GFLOP/s double PlayStation 3 и плата в серверы
  • 14. 2007-2008: быстрое взросление >2000 публикаций про использование CUDA Топовые конференции (Supercomputing) Хорошие готовые библиотеки Новое оборудование: Поддержка двойной точности у всех NVidia: G200 – 800 GFLOP/s single, 100 – double, ATI HD4870: 1000/240 GFLOP/s single/double, но все еще потоковое программирование IBM PowerXCell: ~200/100 GFLOP/s
  • 15. Ускорение приложений на CUDA 2008 г.: NVidia 8800GTX в сравнении с AMD Opteron 248 (2.2GHz, 2 ядра)
  • 16. Современный этап: оборудование Видеокарты: ATI R800 2.7TFLOP/s single, 500 GFLOP/s double Поддержка OpenCL (не только потоковые вычисления) NVidia GF100 (Fermi): Tesla 1.2 TFLOP/s single, 600 GFLOP/s double Geforce GTX 480: 1.3 TFLOP/s single, ~180 GFLOP/s double Для сравнения, топовые x86 CPU: 80-110GFLOP/s (double) GPU-кластеры Промышленные решения (Cray, IBM, Т-платформы) Суперкомпьютеры: Nebulae - №2 в Supercomputer Top500 по реальной производительности, №1 по пиковой.
  • 17. Современный этап: программы Стандарт OpenCL (лето-осень 2009): переносимые GPU-программы Для пользователяускорение multimedia, обработка изображений и видео, 3D-моделирование, инженерные программы... Для программиста много готовых библиотек: линейная алгебра, обработка сигналов, computer vision Для ученого: поддержка в расчетных программах Общего назначения: Matlab, Mathematica Специализированные пакеты: проектирование, компьютерная химия, компьютерная биология, молекулярная динамика
  • 19. Наглядная агитация 4xTesla == Cray XT4 на задачах молекулярной биологии (AMBER11)(слайд с NVidia GPU Technology conference, 22 сентября 2010)
  • 20. NVidia CUDACompute Unified Device Architecture Общий обзор «сверху вниз» Как устроено оборудование И как это отражается в логической структуре программ Минимальные примеры программ Некоторые тонкие моменты Обзор средств программиста и дополнительных библиотек Нет задачи и возможности заменить чтение документации и самостоятельные упражнения
  • 21. Общая схема исполнения программ Все стадии независимы, одновременно можно: Передавать в видеопамять Считать (другие данные) Передавать из видеопамяти
  • 22.
  • 23. 2 специальных процессора (SFU) для сложных функций: 32 потока за 16 тактов, SIMD
  • 25. до 768 потоков на одном SM в «одновременном» режиме
  • 26. потоки объединяются в пачки по 32 потока (warp), которые исполняются SIMD
  • 27. 16 kb разделяемой памяти (shared memory)
  • 28. 8192 32-битных регистраНа 2 SM – один блок обработки текстур с текстурным кэшем и блоком аппаратной интерполяции … TPC TPC TPC TPC TPC TPC Streaming Multiprocessor Texture Processor Cluster Instruction L1 Data L1 Instruction Fetch/Dispatch SM Shared Memory TEX SP SP SP SP SM SFU SFU SP SP SP SP
  • 29. Texture Texture Texture Texture Texture Texture Texture Texture Texture Host Input Assembler Thread Execution Manager Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Parallel DataCache Load/store Load/store Load/store Load/store Load/store Load/store Global Memory G80: общая схема
  • 30. Логическая организация программ Десятки тысяч – миллионы независимых потоков в программе Поток – обрабатывает часть входных данных Потоки объединены в блоки Общая shared memory Синхронизация Блоки объединены в grid Синхронизации нет Grid of Thread Blocks
  • 31. Логическая организация (2) Блок исполняется на одном мультипроцессоре Разные блоки – на разных Порядок не определен Может быть несколько блоков на SM одновременно Нумерация потоков в блоке: 1D, 2D или 3D Нумерация блоков: 1D,2D Каждый поток знает свое положение в сетке и блоке
  • 33. Параметры SM – не догма G92: 16384регистров, до 1024 потоков на SM GF100 (Fermi) 32768 регистров и 32/48 процессоров на SM 1536 потоков (48 warp) на SM 64kb shared memory+L1-cache (16/48 или 48/16 shared/cache) Другие параметры другой оптимальный код Другие улучшения Атомарные операции (G86, G92) Поддержка двойной точности (G200, GF100)
  • 34. Пример: cложение двух векторов Код GPU: складываем два элемента: __global__ void VecAdd(float* A,float* B, float* C, int N) { int i = blockDim.x * blockIdx.x + threadIdx.x; if (i < N) C[i] = A[i]+B[i]; } threadIdx – предопределенная переменная (3-компонентный вектор) – номер потока в блоке blockDim – размерность одного блока (3D) blockIdx – номер блока в сетке (2D)
  • 35. код на CPU // аллоцируем память на GPU size_t size = N * sizeof(float); cudaMalloc((void**)&d_A, size); cudaMalloc((void**)&d_B, size); cudaMalloc((void**)&d_C, size); // копируем данные на GPU cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice); cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice); // запускаем kernel на GPU (1D сетка и блок): int Nthreads = 256; int Nblocks = (N+Nthreads-1)/Nthreads; VecAdd<<<Nblocks,Nthreads>>>(d_A, d_B, d_C, N); // получаем результаты с GPU cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
  • 36. CUDA:С/C++ с небольшими изменениями Спецификаторы типа функции: __global__- GPU, может быть вызвана с CPU (с параметрами) __device__ - GPU, вызывается из __global__ __host__ - CPUРекурсия и указатели на функции: только Fermi (GF100) Спецификаторы местоположения переменной __device__ - глобальная память, R/W __constant__ - константная память, R/O __shared__ - shared memory, R/W, локальна в блоке Автоматические переменные – могут быть в регистрах, если известен размер и регистров достаточно. Иначе – local memory, т.е. живут в медленной глобальной памяти
  • 37. Типы данных и переменные Скалярные:char, short, int, long,longlong, float, double (и беззнаковые для целых) Векторные: <=32 бит/компонент – до 4 элементов (uchar2,float4) 64 бита – 2 элемента (double2, longlong2) Векторных операций НЕТ: c.x=a.x+b.x работает, c=a+b - нет dim3 – тип для задания размера сетки блоков Встроенные переменные: gridDim, blockDim– размер сетки и блока (dim3) blockIdx, threadIdx– номер блока и потока (dim3) warpSize – ширина SIMD (пока всегда 32)
  • 38. Двумерные блоки например, для двумерных моделей На CPU: dim3 blockSize(16, 16); // некратным размером сетки пренебрегаем... dim3 gridSize(width/blockSize.x, height/blockSize.y); myKernel<<<gridSize,blockSize>>>(…..) На GPU uint x = blockIdx.x*blockDim.x+threadIdx.x; uint y = blockIdx.y*blockDim.y +threadIdx.y;
  • 39. Синхронизация, атомарные операции Глобальная синхронизация всех блоков – завершение kernel __syncthreads() – синхронизация потоков блока Атомарные сложения, вычитания и т.п. (atomicAdd() и т.д.) - G86+ Shared или Global memory (G86 – только global) Атомарное исполнение Медленные
  • 40. Скалярное произведение Накапливаем частные произведенияпо потокам: __global__ result; shared__ float psum[NTHREADS]; psum[threadIdx.x] = 0; for(j=0;j<K*NTHREADS;j+=NTHREADS) psum[threadIdx.x] += A[base+j]*B[base+j]; __syncthreads(); // Складываем для блока if(threadIdx.x == 0) { for(j=1;j<blockDim.x;j++) psum[0]+=psum[j]; // синхронизации не надо!! 0-йthread atomicAdd(&result,psum[0]); }
  • 41. Тонкости Оптимальный доступ к глобальной памяти Особенности доступа к shared memory Условные операции Распределение блоков по процессорам
  • 42. Доступ к глобальной памяти Сложение векторов, 16 сложений на thread: ___________________________________________________ int j,base = (blockDim.x*blockIdx.x+threadIdx.x)*16; for(j=0;j<16;j++) C[base+j] = A[base+j] + B[base+j] Thread0: A[0], A[1] Thread1: A[16], A[17] Весь Warp обращается c «размахом» в 512 слов ______________________________________________________ int j,base = (blockDim.x*blockIdx.x)*16+threadIdx.x; for(j=0;j<blockDim.x*16;j+=blockDim.x) C[base+j] = A[base+j] + B[base+j] Thread0: A[0], A[blockDim.x]... Thread1: A[1], A[blockDim.x+1].... Весь Warp обращается к соседним словам Второй вариант – coalesced access: доступ к соседним адресам
  • 43. Доступ к глобальной памяти - 2 Прямые рекомендации из Programming Guide: Оптимально, когда все потоки одного (полу)-warp*обращаются к одному 128-байтному сегменту Для 16-байтных элементов (вектор) – два подряд 128-байтных сегмента. В правильном порядке – k-йthread к k-му элементу в сегменте. Идеальная ситуация: Array[base + treadIdx.x]Array[base] – выровнен на 128 байт
  • 44. Разделяемая память Разделена на банки 16 банков на G80-G200, 32 на GF100 Interleave 4 байта Два потока в 1 банк =>конфликт, каждый конфликт – 4 такта ожидания Оптимальный доступ array[threadIdx]
  • 45. Нет конфликта банков Bank 0 Thread 0 Bank 0 Thread 0 Bank 1 Thread 1 Bank 1 Thread 1 Bank 2 Thread 2 Bank 2 Thread 2 Bank 3 Thread 3 Bank 3 Thread 3 Bank 4 Thread 4 Bank 4 Thread 4 Bank 5 Thread 5 Bank 5 Thread 5 Bank 6 Thread 6 Bank 6 Thread 6 Bank 7 Thread 7 Bank 7 Thread 7 Bank 15 Thread 15 Bank 15 Thread 15
  • 46. Конфликт банков Bank 0 Bank 1 Thread 0 Bank 2 Thread 1 Bank 3 Thread 2 Bank 4 Thread 3 Bank 5 Thread 4 Bank 6 Bank 7 Thread 8 Thread 9 Bank 15 Thread 10 Thread 11 GF100: несколько чтений разных потоков по одному адресу (не банку) – не приводят к конфликту (broadcast данных)
  • 47. Условные операции SIMD поэтому если в одном warp разные ветки if, их исполнение будет последовательным: if (threadIdx.x %2) { четные ветки стоят, нечетные работают} else { четные работают, нечетные стоят }
  • 48. Распределение блоков по SM Не меньше одного блока т.е. блок должен пролезать по ресурсам: Общее число потоковв блоке < лимита оборудования Требуемое количество shared memory< лимита Общее количество регистров (регистров на поток * число потоков) < лимита Несколько блоков на SM – если достаточно ресурсов (регистров, shared memory, потоков) G80-G200 – передача параметров в shared mem, 2 X 8192 – не влезет в 16 килобайт
  • 49. Загрузка SM (occupancy) Отношение числа работающих warps к из возможному количеству В общем случае, к 100% надо стремиться: Прячется латентность доступа к памяти Но мало регистров (G92 – 16 регистров/thread) Альтернативный подход: Мало потоков (128-192-256 на SM) Зато много регистров на поток Полезно для блочных алгоритмов Подробнее: Volkov, V. 2010. Use registers and multiple outputs per thread on GPUhttp://www.cs.berkeley.edu/~volkov/volkov10-PMAA.pdf
  • 50. Разное Целая арифметика: G80-G200: 24-бита – быстрая, 32 бита – медленная GF100 – 32 бита – быстрая, 24 бита - медленная Текстуры: 1-2-3D-массивы Кэшируются, кэш локален по координатам (эффективное кэширование по столбцам, при последовательном доступе – медленнее global memory) Аппаратная интерполяция
  • 51. Продолжение..... Документация NvidiaОчень хорошая!http://developer.nvidia.com/object/cuda_download.html CUDA Programming Guide CUDA Reference Guide CUDA Best Practices Guide Примеры SDK и документация к нимhttp://developer.download.nvidia.com/compute/cuda/sdk/website/samples.html Форумы Nvidiahttp://forums.nvidia.com/index.php?showforum=62
  • 52. Программные средства CUDA Toolkit – компилятор + библиотеки Интегрируется с Visual C++ (добавление правил компиляции для .cu) Отладчик – gdb (командная строка) Visual Profiler – не на уровне отдельных строк кода Parallel Nsight Пошаговая отладка Глобальный профайлинг Standard (бесплатная) и Professional (бесплатная для ВУЗов) версии CUDA-x86 Был эмулятор, но в Cuda 3.x удален PGI обещает компилятор
  • 53.
  • 54. Компиляция в внешний .cubin-файл и загрузка на runtimeФинальную компиляцию реальные коды делает драйвер видеокарты NVCC CPU Code PTX Code Virtual Physical PTX to Target Compiler G80 … GPU Target code
  • 55. Два API CUDA C API: реализуется внешней библиотекой cudart Высокоуровневое, более удобное удобная поддержка нескольких контекстов (например для использования в многопоточных программах) CUDA Driver API: Аналогично по возможностям Не требует дополнительных библиотек Больше работы программисту
  • 56. Альтернативы CUDA OpenCL CAL/IL (Compute Abstraction Layer/Intermediate Language) Только видеокарты ATI Потоковое программирование Плохо поддерживается DirectX 11 (DirectCompute) Только Windows
  • 57. OpenCL Многоплатформенный стандарт Необычайно похож на CUDA Driver API Детали: Язык C для kernels, другие ключевые слова Компиляция из исходных текстов на ходу («в драйвере») Уже две версии (1.0 и 1.1) Нестандартная конфигурация поддерживается через «расширения»
  • 58. Сложение векторов Код GPU: __kernel void VectorAdd(__global const float* a,__global const float* b,__global float* c, int N) { int iGID = get_global_id(0); if (iGID < N) c[iGID] = a[iGID] + b[iGID]; }
  • 59. Код CPU // Создаем контекст GPU (до того был поиск устройств...) Context = clCreateContext(0, 1, &cdDevice, NULL, NULL, &ciErr1); // и очередь команд CommandQueue = clCreateCommandQueue(Context, cdDevice, 0, &ciErr1); // Аллоцируем массив(ы) на GPU cmDevSrcA = clCreateBuffer(Context, CL_MEM_READ_ONLY, sizeof(cl_float) * szGlobalWorkSize, NULL, &ciErr1); …. И еще два аллоцирования .... // Создаем (компилируем) программу из исходных текстов cpProgram = clCreateProgramWithSource(Context, 1, (const char **)&cSourceCL, &szKernelLength, &ciErr1); // создаем из нее kernel ckKernel = clCreateKernel(cpProgram, "VectorAdd", &ciErr1); // задаем ему аргумент(ы) clSetKernelArg(ckKernel, 0, sizeof(cl_mem), (void*)&cmDevSrcA); .... И еще три аргумента ...... // В очередь команд помещаем копирование данных и запуск kernel, все асинхронно clEnqueueWriteBuffer(CommandQueue, cmDevSrcA, CL_FALSE, 0, sizeof(cl_float) * szGlobalWorkSize, srcA, 0, NULL, NULL); .... И еще одно копирование.... clEnqueueNDRangeKernel(CommandQueue, ckKernel, 1, NULL, &szGlobalWorkSize, &szLocalWorkSize, 0, NULL, NULL); // В очередь команд помещаем синхронное чтение результата clEnqueueReadBuffer(CommandQueue, cmDevDst, CL_TRUE, 0, sizeof(cl_float) * szGlobalWorkSize, dst, 0, NULL, NULL);
  • 60. CUDA  OpenCL AMD: Porting CUDA to OpenCLhttp://developer.amd.com/zones/OpenCLZone/Pages/portingcudatoopencl.aspx
  • 61. Переносимость и производительность Переносимыйкод (NVidia, ATI,x86, Cell) Производительность не переносится: Либо используем векторные типы на векторных архитектурах (ATI, Cell) и получаем непереносимый код Либо код получается переносимый и в разы медленнее Перенос CUDA  OpenCL – потеря 20-30%. Компилятор?? CUDA всегда будет впереди т.к. нет этапа согласований с рабочей группой
  • 62. OpenCL и видеокарты ATI Человеческий интерфейс (в отличие от CAL/IL) HD5870 – производительность примеров SDK - на уровне GTX280 (в разы ниже ожидаемого) HD4xxx – производительность плохая т.к. нет shared memory (эмуляция через глобальную) Плохая документация (в сравнении с...) Но что делать, если попалось такое оборудование и не хочется ассемблера.....
  • 63.
  • 64. Обработка сигналов, обработка изображений: десятки раз
  • 65.
  • 66. На каких задачах GPU медленнее? Задачи, которые не распараллеливаются на тысячи независимых потоков State machine, операции со строками Обход (одного большого) графа Неподходящий размер working set: На GPU 1-3 Mbочень быстрой памяти На CPU 4-8-12-64Mb L2 cache Случайный доступ к большому массиву Видеопамять медленнее при случайном доступе Низкая арифметическая интенсивность
  • 67. Как с этим жить? Дешевый способ увеличить производительность в 5-10-100 раз, в зависимости от задачи. Рекомендации по самостоятельному использованию: Учиться на CUDA Использовать OpenCL если действительно нужна переносимость Если нет GPU, а попробовать хочется Использовать ATI и CAL/IL если нужна максимальная производительность на потоковых операциях Используйте mixed-precision схемы (на CPU тоже очень полезно!)
  • 68. Как с этим жить - 2 Используйте библиотеки: CUBLAS, CUFFT, CUSPARSE – входят в CUDA SDK CUDPP, MAGMA, GATLAS, OpenCV – 3rd party и бесплатны ACML-GPU для ATI .... библиотек уже много.... Расширения для Matlab Parallel Computing Toolbox (R2010b) Jacket GPUmat, ViennaCL
  • 69. CUDA: Университетские курсы University of Urbana самый первыйдоступный курс курс: http://courses.engr.illinois.edu/ece498/al/Syllabus.html (доступны слайды и запись голоса). Курс по CUDA, читаемый на ВМКЗаписи 2009 года: http://esyr.org/lections/audio/cuda_2009_summer/ и http://esyr.org/video/cuda/Записи 2010 года: ftp://geophyslab.srcc.msu.ru/Events/CUDA2010/Google-группа к этому курсу: http://groups.google.ru/group/cudacsmsusu/
  • 70. CUDA: книги На русском А. В. Боресков, А. А. Харламов Основы работы с технологией CUDA (+ CD-ROM)http://www.ozon.ru/context/detail/id/5080841/ На английском Programming Massively Parallel Processors: A Hands-on Approach, David B. Kirk, Wen-mei W. Hwuhttp://www.amazon.com/Programming-Massively-Parallel-Processors-Hands/dp/0123814723/ref=sr_1_1?ie=UTF8&s=books&qid=1284301217&sr=8-1 CUDA by Example: An Introduction to General-Purpose GPU Programming by Jason Sanders and Edward Kandrothttp://www.amazon.com/CUDA-Example-Introduction-General-Purpose-Programming/dp/0131387685/ref=sr_1_4?ie=UTF8&s=books&qid=1284301217&sr=8-4
  • 71. Литература OpenCL Сайт с описанием стандарта: http://www.khronos.org/opencl/далее по ссылкам. Обзор «OpenCL: A Parallel Programming Standard for Heterogeneous Computing Systems» http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5457293 Документы AMD по миграции с CUDA на OpenCL: http://developer.amd.com/documentation/articles/pages/OpenCL-and-the-ATI-Stream-v2.0-Beta.aspx#four http://developer.amd.com/gpu/ATIStreamSDK/pages/TutorialOpenCL.aspx Документы NVIdia по программированию OpenCL: Programming Guide: http://developer.download.nvidia.com/compute/cuda/3_1/toolkit/docs/NVIDIA_OpenCL_ProgrammingGuide.pdf Best Practices Guide: http://developer.download.nvidia.com/compute/cuda/3_1/toolkit/docs/NVIDIA_OpenCL_BestPracticesGuide.pdf Code Samples: http://developer.download.nvidia.com/compute/opencl/sdk/website/samples.html Книги: The OpenCL Programming Book http://www.fixstars.com/en/company/books/opencl/
  • 72. Литература: Разное Debunking the 100X GPU vs CPU Myth: an Evaluation of Throughput Computing on CPU and GPUhttp://www.hwsw.hu/kepek/hirek/2010/06/p451-lee.pdf Относиться с осторожностью, авторам статьи (инженерам Intel) обидно за свои процессоры и они тянут одеяло в свою сторону
  • 73. Спасибо за внимание! Задавайте вопросы