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

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

on

  • 24,822 views

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

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

Statistics

Views

Total Views
24,822
Slideshare-icon Views on SlideShare
9,168
Embed Views
15,654

Actions

Likes
3
Downloads
0
Comments
0

7 Embeds 15,654

http://www.gpgpu.ru 15610
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
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • Параллельное программирование
      На современных видеокартах(GPGPU)
      Алексей Тутубалинwww.gpgpu.rulexa@lexa.ru
    • План встречи
    • Параллельные вычисления: зачем?
      • Производительности всегда не хватает
      • Рост производительности 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) и векторные инструкции
      Программистам от параллельности деваться некуда
    • Параллельные вычисления
      Как?
      Одновременное исполнение независимых вычислений на разных процессорах с последующей синхронизацией
      Проблемы:
      Правило Амдала: ускорение=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)
      • 8 простых процессоров (SP): исполняют 32 потока за 4 такта в SIMD-режиме
      • 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 – неоптимизированный ассемблер, дальнейшие варианты:
      • Компиляция в один executable
      • Компиляция в внешний .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 НАСТОЛЬКО быстрее?
      • Линейная алгебра: 5-8раз
      • Обработка сигналов, обработка изображений: десятки раз
      • Некоторые задачи (молекулярная динамика, N-body): бывают сотни раз
    • Вот почему:
      Другой аппаратный дизайн:
      CPU – оптимизация под любые задачи (включая очень плохой код) и низкую латентность.
      GPU – оптимизация под общую производительность и только высокопараллельные задачи.
      Быстрая память:
      В разы выше bandwidth видеопамяти
      Больше очень быстрой памяти(2-3Mbпротив 32-256Kb L1 cache CPU)
      Аппаратная поддержка ряда функций (exp, sin, cos, pow, log….): разница с CPU в десятки и даже сотни (!) раз
      Часто сравнивают с неоптимизированным кодом (а другого и нет, писать руками SSE-инструкции скучно)
    • На каких задачах GPU медленнее?
      Задачи, которые не распараллеливаются на тысячи независимых потоков
      State machine, операции со строками
      Обход (одного большого) графа
      Неподходящий размер working set:
      На GPU 1-3 Mbочень быстрой памяти
      На CPU 4-8-12-64Mb L2 cache
      Случайный доступ к большому массиву
      Видеопамять медленнее при случайном доступе
      Низкая арифметическая интенсивность
    • Как с этим жить?
      Дешевый способ увеличить производительность в 5-10-100 раз, в зависимости от задачи.
      Рекомендации по самостоятельному использованию:
      Учиться на CUDA
      Использовать OpenCL
      если действительно нужна переносимость
      Если нет GPU, а попробовать хочется
      Использовать ATI и CAL/IL если нужна максимальная производительность на потоковых операциях
      Используйте mixed-precision схемы (на CPU тоже очень полезно!)
    • Как с этим жить - 2
      Используйте библиотеки:
      CUBLAS, CUFFT, CUSPARSE – входят в CUDA SDK
      CUDPP, MAGMA, GATLAS, OpenCV – 3rd party и бесплатны
      ACML-GPU для ATI
      .... библиотек уже много....
      Расширения для Matlab
      Parallel Computing Toolbox (R2010b)
      Jacket
      GPUmat, ViennaCL
    • 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/
    • 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
    • Литература 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/
    • Литература: Разное
      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) обидно за свои процессоры и они тянут одеяло в свою сторону
    • Спасибо за внимание!
      Задавайте вопросы