Skip to content

GPGPUCourse/GPGPUSpeedupGuidelines

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Остальные задания.

Build Status

Видеозапись лекция (две части)

Presentation on ICCV 2021 Presentation on ICCV 2021

Используем профилировщик/санитайзер

Первая лекция:

  1. Статья 01: как установить NVIDIA драйвер и CUDA, пример запуска профилировщика NVIDIA Nsight Compute для задачи суммирования двух векторов
  2. Статья 02: как запустить санитайзер compute-sanitizer --tool initcheck для проверки что вся видеопамять была инициализирована (не считываем случайный мусор)

Вторая лекция:

  1. Статья 03: на примере задачи суммирования элементов массива исследуем и профилируем:
  • 3.1) Как отладить ошибку через printf со стороны кернела на видеокарте
  • 3.2) Иногда кэш спасает скорость работы кернела вопреки non-coalesced паттерну доступа
  • 3.3) Как помешать кэшу спасать нас
  • 3.4) Как форсировать чтения памяти быть non-coalesced
  1. Статья 04: на примере задачи суммирования элементов массива через редукцию в локальной памяти:
  • 4.1) Как проверить нет ли в кернеле гонок в обращениях к локальной памяти (compute-sanitizer --tool racecheck)
  • 4.2) Какие есть виды гонок (на примере RAW, WAR гонок)
  1. Статья 05: на примере задачи суммирования элементов массива через редукцию проверяем что обращение за пределами массива легко поймать (compute-sanitizer --tool memcheck)
  2. Статья 06: на примере задачи суммирования элементов массива через редукцию анализируем поведение программы через Timeline визуализацию в NVIDIA Nsight Compute

Примеры профилирования/ускорения

  1. Пример профилирования и ускорения: случай когда тормозит трансфер данных на Vulkan (VRAM -> CPU) - помогает увидеть timeline + видеть в логе строку вида processing done in 1234 s = 20% IO + 10% CPU + 5% upload to VRAM + 30% GPU + 35% read from VRAM + взвешивать килограммами

  2. Пример профилирования и ускорения: в случае когда CPU-часть занимает существенную долю времени (например 40%) - какой потенциальный прирост от обработки в два потока? А если ситуация другая - 80% времени CPU и 20% GPU? Что с этим делать?

  3. Пример профилирования и ускорения: если есть переход из локальной системы координат камеры A в мир, и затем из мира в локальную систему координат второй камеры B

  4. Пример профилирования и ускорения: если какой-то кусок-патч картинки нужно целиком подвергнуть сложной трансформации - вместо проецирования каждого пикселя этого патча - проецируем центр и производные рассчитываем, получили чуть загрубленую трансформацию

Примеры общего подхода

  1. Пример подхода: пусть обработка выглядит как IO -> CPU -> GPU, как решить сколько потоков нужно на IO? Сколько на CPU?

  2. Пример подхода: если есть рандомность в алгоритме - как реализовать ее в модели массового параллелизма? А если хочется детерминизма результата?

  3. Пример подхода: как в растеризационном пайплайне рассчитать площадь треугольников измеряемых в количестве их пикселей-фрагментов (которые выжили после depth-test в фрагментном шейдере)?

  4. Пример подхода: как распределить по узлам кластера задачу "для каждого треугольника перечислить перечен камер которые его видят". А что если треугольники не влезают в память? Как сделать это с out-of-core свойством?

  5. Пример подхода: если надо писать что-то многопоточно в пиксели картинки, как это делать без точки синхронизации, т.е. без одного общего лока? (случай CPU, случай GPU, случай 64-битных данных, случай произвольных по размеру)

  6. Пример подхода: если задача на некоторой 2D решетке (например картинка) и не требует абсолютной точности - то можно часто прорядить и работать в каждом втором ряду-столбике. А потом несколько итераций уточнить ответ уже для каждого пикселя.

  7. Пример подхода: если задача на некоторой 2D решетке (например картинка) и не требует абсолютной точности - то можно сначала работать на х32 раза меньшей детальности, затем на х16, ..., наконец, на оригинальном разрешении. Очень много общего с предыдущей идеей про прореживание.

  8. Пример подхода: как ускорить растеризацию треугольников?

Список тем: примеры алгоритмов

  1. Пример алгоритма: пусть на видеокарте есть code divergence в coarse-to-fine схеме в задаче подобной приложению чартов в атлас. Как оставить схему но получить ускорение разобравшись с code divergence?

  2. Пример алгоритма: пусть на CPU есть алгоритм СНМ (система непересекающихся множеств) с тяжелыми inplace вычислениями "кто из соседних пикселей действительно сосед - т.е. дорогая проверка стоит ли провести с ним union". Как ускорить за счет делегирования на видеокарту проверку "соседства" оставив СНМ-операции на процессоре?

  3. Пример алгоритма: пусть на CPU есть алгоритм СНМ (система непересекающихся множеств), как ускорить за счет многопоточности?

  4. Пример алгоритма: если есть алгоритм в котором трассировка лучей, как его ускорить на видеокарте (возможно с потерей точности)? Как переделать алгоритм в котором есть не разбиваемая задача "трассируй луч перешагивая по ячейкам пространства" в парадигму "есть N задач каждая O(1)".

Почему в этом репозитории и OpenCL, и CUDA?

Этот проект иллюстрирует как написать код для видеокарты посредством OpenCL и затем скомпилировать его в т.ч. для исполнения через CUDA. Это дает замечательную возможность использовать инструментарий CUDA:

  • профилировщик - NVIDIA Nsight Compute: позволяет посмотреть timeline выполнения кернелов, насколько какой кернел насытил пропускную способность видеопамяти/локальной памяти или ALU, число используемых регистров и локальной памяти (и соответственно насколько высока occupancy), а так же он часто явно подскажет в чем может быть основная потеря скорости работы кернела
  • санитайзер - compute-sanitizer --tool memcheck (бывший cuda-memcheck): позволяет проверить что нет out-of-bounds обращений к памяти (если есть - укажет проблемную строку в кернеле)
  • санитайзер - compute-sanitizer --tool racecheck (бывший cuda-memcheck): позволяет проверить что нет гонок между потоками рабочей группы при обращении к локальной памяти (т.е. что нигде не забыты барьеры). Если гонка есть - укажет на ее характер (RAW/WAR/WAW) и на строки в кернеле (обеих операций участвующих в гонке)

Ориентиры

Здесь предложена трансляция в CUDA на примере задачи C=A+B, трансляция не исчерпывающая, но во многих простых случаях должна работать. Она реализована благодаря файлу с макросами которые транслируют OpenCL вызовы в CUDA вызовы - libs/gpu/libgpu/cuda/cu/opencl_translator.cu.

Дополнительные ориентиры:

  • CMakeLists.txt: Поиск CUDA-компилятора, добавление для NVCC компилятора флажка 'сохранять номера строк' (нужно чтобы cuda-memcheck мог указывать номера строк с ошибками), компиляция через cuda_add_executable.
  • aplusb.cu: CUDA-кернел транслируется из OpenCL-кернела посредством макросов, вызов кернела через функцию cuda_aplusb
  • main01_aplusb.cpp: декларация функции cuda_aplusb, инициализация CUDA-контекста, вызов функции вызывающий кернел
  • Запись лекции с одного из прошлых прочтений - есть пояснения про этот транслятор и про отличия CUDA

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages