От 6.8 секунд к 23 миллисекундам: эволюция производительности
В блоге NVIDIA Developer Tools подробно разобран практический кейс оптимизации конвейера обработки изображений. Исходный код, написанный с использованием базовых вызовов CUDA, выполнялся 6.8 секунды на трех изображениях. После применения шести шагов оптимизации с использованием современного стека CUDA Compute (CCCL), библиотек CUB и асинхронных потоков, время выполнения сократилось до 23 миллисекунд. Это ускорение составляет 300x.
Ключевые метрики оптимизации приведены в таблице ниже:
| Этап оптимизации | Технология/Инструмент | Результат |
|---|---|---|
| Замена ручных ядер | CUB (device/block primitives) | Медианный расчет: 2.1 с → 773 мкс (ускорение 2,717x) |
| Управление памятью GPU | CCCL pooled containers | Сокращение накладных расходов на аллокацию, общее ускорение конвейера в 2.6x |
| Передача Host-to-Device | cuda::host_buffer (pinned memory) | Ускорение передачи данных в 10x |
| Параллелизм и асинхронность | OpenMP + cuda::stream + async copy | Итоговое время: ~23 мс (300x быстрее оригинала) |
Безопасность и отладка: CCCL и Compute Sanitizer
Первый шаг оптимизации касается не только скорости, но и надежности. NVIDIA рекомендует отказаться от старой модели индексации в пользу современного API CCCL, который четко разделяет глобальные и блочные координаты. Это позволяет избежать ошибок выхода за границы памяти (out-of-bounds), которые часто остаются незамеченными. Для их выявления используется Compute Sanitizer, интегрированный в современный инструментарий.
Ускорение вычислений через CUB
Вместо написания собственных алгоритмов сортировки (например, пузырьковой сортировки для медианы в исходном коде), разработчики заменили ядра на оптимизированные примитивы CUB (CUDA Unbound). Это дало кратный прирост производительности: время вычисления медианы на одно изображение упало с 2.1 секунды до 773 микросекунд.
Асинхронность: скрытие задержек памяти
Финальный шаг достигнут за счет использования OpenMP для распределения потоков и назначения каждого потока на отдельный cuda::stream. Асинхронные копии данных (cuda::copy_bytes) позволяют перекрывать передачу данных с вычислениями. Именно эта техника скрытия задержек памяти и вычислений позволила достичь итогового времени в 23 мс.
Полный код примера и интерактивный ноутбук для Google Colab доступны на странице NVIDIA Developer Blog.
Источник: NVIDIA dev blog ↗
