• Save
Параллельное программирование на современных видеокартах
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

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

  • 25,485 views
Uploaded on

Слайды со встречи на физфаке МГУ, 29 сентября 2010

Слайды со встречи на физфаке МГУ, 29 сентября 2010

More in: Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
25,485
On Slideshare
9,581
From Embeds
15,904
Number of Embeds
7

Actions

Shares
Downloads
0
Comments
0
Likes
3

Embeds 15,904

http://www.gpgpu.ru 15,860
http://new.gpgpu.ru 12
http://www2.gpgpu.ru 12
http://feeds.lexa.ru 9
http://webcache.googleusercontent.com 8
http://hghltd.yandex.net 2
http://translate.googleusercontent.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Параллельное программирование
    На современных видеокартах(GPGPU)
    Алексей Тутубалинwww.gpgpu.rulexa@lexa.ru
  • 2. План встречи
  • 3. Параллельные вычисления: зачем?
    • Производительности всегда не хватает
    • 4. Рост производительности CPU сильно замедлился
  • The Landscape of Parallel Computer Research: A View from Berkeley (2006)
    http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-183.pdf
    - старые парадигмы во многом устарели, параллельность – единственный (на сегодня) путь
    Ответ индустрии оборудования: многоядерностьCPU
    • а до того – многопроцессорные машины с общей памятью (SMP) и векторные инструкции
    Программистам от параллельности деваться некуда
  • 5. Параллельные вычисления
    Как?
    Одновременное исполнение независимых вычислений на разных процессорах с последующей синхронизацией
    Проблемы:
    Правило Амдала: ускорение=P – доля программы, которую можно распараллелить, N – число потоков исполнения
    Слишком маленькие независимые блоки много затрат на синхронизацию
    Сложно программировать (много объектов, синхронизация, критические секции)
  • 6. Параллельные системы
  • 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
    Специализированные пакеты: проектирование, компьютерная химия, компьютерная биология, молекулярная динамика
  • 18. Современный этап: производительность
  • 19. Наглядная агитация
    4xTesla == Cray XT4 на задачах молекулярной биологии (AMBER11)(слайд с NVidia GPU Technology conference, 22 сентября 2010)
  • 20. NVidia CUDACompute Unified Device Architecture
    Общий обзор «сверху вниз»
    Как устроено оборудование
    И как это отражается в логической структуре программ
    Минимальные примеры программ
    Некоторые тонкие моменты
    Обзор средств программиста и дополнительных библиотек
    Нет задачи и возможности заменить чтение документации и самостоятельные упражнения
  • 21. Общая схема исполнения программ
    Все стадии независимы, одновременно можно:
    Передавать в видеопамять
    Считать (другие данные)
    Передавать из видеопамяти
  • 22. Архитектура G80
    До 16 одинаковых мультипроцессоровна чипе
    Общая глобальная память (R/W): медленная и много (до 1.5Gb)
    Общая константная память (RO): быстрая и мало
    Общий планировщик потоков (блоками)
    Общий исполняемый код на вечь чип
    G80Streaming Multiprocessor (SM)
    • 8 простых процессоров (SP): исполняют 32 потока за 4 такта в SIMD-режиме
    • 23. 2 специальных процессора (SFU) для сложных функций: 32 потока за 16 тактов, SIMD
    • 24. Один диспетчер команд
    • 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
    Каждый поток знает свое положение в сетке и блоке
  • 32. Иерархия памяти
  • 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. Подробности компиляции
    float4 me = gx[gtid];
    me.x += me.y * me.z;
    C/C++ CUDA
    Application
    CPU-code компилируется родным компилятором
    PTX – неоптимизированный ассемблер, дальнейшие варианты:
    • Компиляция в один executable
    • 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. Почему GPU НАСТОЛЬКО быстрее?
    • Линейная алгебра: 5-8раз
    • 64. Обработка сигналов, обработка изображений: десятки раз
    • 65. Некоторые задачи (молекулярная динамика, N-body): бывают сотни раз
  • Вот почему:
    Другой аппаратный дизайн:
    CPU – оптимизация под любые задачи (включая очень плохой код) и низкую латентность.
    GPU – оптимизация под общую производительность и только высокопараллельные задачи.
    Быстрая память:
    В разы выше bandwidth видеопамяти
    Больше очень быстрой памяти(2-3Mbпротив 32-256Kb L1 cache CPU)
    Аппаратная поддержка ряда функций (exp, sin, cos, pow, log….): разница с CPU в десятки и даже сотни (!) раз
    Часто сравнивают с неоптимизированным кодом (а другого и нет, писать руками SSE-инструкции скучно)
  • 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. Спасибо за внимание!
    Задавайте вопросы