CPU, GPU И RAM

CUDA: как проверить перекрытие копирования и вычислений

В этом материале
ГЛАВНОЕ ЗА МИНУТУ

Наличие Async в имени вызова не доказывает перекрытие: нужны выполненные условия и наблюдаемое пересечение интервалов.

Отличить отправку от исполнения

Асинхронный вызов может быстро вернуть управление CPU, но это ещё не показывает одновременное выполнение копирования и kernel на GPU. Время возврата функции и интервал работы устройства имеют разные границы. CUDA Best Practices Guide описывает условия перекрытия передач и вычислений, включая возможности устройства, память хоста и streams. До оптимизации фиксируют конкретную гипотезу: какой transfer должен перекрыться с каким вычислением и почему между ними нет обязательной зависимости. Если kernel использует данные именно этой незавершённой передачи, простая перестановка вызовов в разные streams не отменяет необходимость корректного порядка доступа к этим данным.

Проверить предварительные условия

В паспорте эксперимента сохраняют GPU, версию CUDA и драйвера, свойства устройства, тип host memory и используемые streams. Для рассматриваемого пути передачи проверяют требования документации к закреплённой памяти. Затем выписывают зависимости между буферами и операциями, включая возможную синхронизацию по умолчанию. Нельзя считать, что несколько streams автоматически означают независимую работу. Библиотека может вставлять ожидания, а приложение — переиспользовать один буфер слишком рано. Схема владения должна объяснять, кто пишет и читает каждый участок памяти. Ускорение с повреждёнными данными не является успешным overlap, даже если timeline выглядит убедительно и средняя длительность стала меньше.

Создать последовательный контроль

Первый вариант выполняет известный объём передачи и вычислений последовательно. Второй использует тот же объём и явно заданные независимые части работы. Для обоих сохраняют прогрев, размеры, число повторов и проверку результата. Не сравнивают один большой kernel с другим алгоритмом: тогда выигрыш нельзя приписать перекрытию. Общую длительность измеряют на одинаковых границах завершения. CUDA Runtime Event API описывает запись событий и измерение интервалов; корректность результата зависит от того, где события расположены относительно исследуемой работы. Событие в одном stream не следует произвольно трактовать как завершение всех операций устройства в других streams.

Смотреть на timeline и остаточные паузы

Основной артефакт — временная схема передач, kernels и ожиданий вместе с конфигурацией запуска. Если интервалы не пересекаются, последовательно проверяют поддержку hardware, тип памяти, зависимости и скрытую синхронизацию. Если пересечение есть, но итоговое время не уменьшилось, исследуют конкуренцию за память и размер работы: overlap способен изменить длительность самих операций. Не следует складывать отдельные timings и объявлять разницу доказанной экономией без общего контрольного интервала. Также проверяют CPU, который подготавливает следующие данные. Его задержка может оставить GPU без работы и создать паузы, ошибочно похожие на отсутствие способности устройства выполнять операции параллельно.

Ограничить практическое заключение

Отчёт указывает, какие именно операции пересекались, какой общий интервал изменился и сохранилась ли корректность данных. Полезны bandwidth памяти для LLM и пропускная способность PCIe GPU. Результат одного синтетического случая не обещает ускорения любой модели или production batch. У inference-движка могут быть другие размеры, потоки и зависимости, которые надо наблюдать отдельно. Оптимизацию принимают по проверенному рабочему сценарию, а не по имени Async или числу streams в коде. Вместе с результатом сохраняют версии и ограничения опыта, чтобы следующий запуск мог воспроизвести смысл сравнения, а не только команду.

← Все материалы