API драйвера CUDA и среда выполнения CUDA
При написании приложений CUDA вы можете работать либо на уровне драйвера, либо на уровне среды выполнения, как показано на этом образе (библиотеки CUFFT и CUBLAS для углубленной математики):
(источник: tomshw.it)
Я полагаю, что компромисс между ними заключается в повышении производительности API низкого уровня, но за счет увеличения сложности кода. Каковы конкретные различия и есть ли какие-то существенные вещи, которые вы не можете сделать с высокоуровневым API?
Я использую CUDA.net для взаимодействия с C#, и он построен как копия драйвера API. Это поощряет написание большого количества довольно сложного кода на C#, в то время как эквивалент C++ будет проще с использованием API времени выполнения. Есть ли что-то, чтобы выиграть, делая это таким образом? Единственное преимущество, которое я вижу, состоит в том, что проще интегрировать интеллектуальную обработку ошибок с остальной частью кода C#.
4 ответа
Среда выполнения CUDA позволяет компилировать и связывать ваши ядра CUDA в исполняемые файлы. Это означает, что вам не нужно распространять файлы cubin вместе с вашим приложением или загружать их через API драйвера. Как вы заметили, как правило, его проще использовать.
В отличие от API драйвера сложнее программировать, но он обеспечивает больший контроль над использованием CUDA. Программист должен непосредственно заниматься инициализацией, загрузкой модуля и т. Д.
Очевидно, более подробную информацию об устройстве можно запросить через API драйвера, чем через API времени выполнения. Например, свободная память, доступная на устройстве, может быть запрошена только через API драйвера.
Из Руководства программиста CUDA:
Он состоит из двух API:
- Низкоуровневый API, называемый API драйвера CUDA,
- API более высокого уровня, называемый API времени выполнения CUDA, который реализован поверх API драйвера CUDA.
Эти API-интерфейсы являются взаимоисключающими: приложение должно использовать либо одно, либо другое.
Среда выполнения CUDA упрощает управление кодом устройства, обеспечивая неявную инициализацию, управление контекстом и управление модулями. Хост-код C, сгенерированный nvcc, основан на среде выполнения CUDA (см. Раздел 4.2.5), поэтому приложения, которые ссылаются на этот код, должны использовать API времени выполнения CUDA.
Напротив, API драйвера CUDA требует больше кода, его сложнее программировать и отлаживать, но он предлагает лучший уровень управления и не зависит от языка, поскольку он имеет дело только с объектами cubin (см. Раздел 4.2.5). В частности, более сложно конфигурировать и запускать ядра с использованием API драйвера CUDA, поскольку конфигурация выполнения и параметры ядра должны указываться с помощью явных вызовов функций вместо синтаксиса конфигурации выполнения, описанного в разделе 4.2.3. Кроме того, эмуляция устройства (см. Раздел 4.5.2.9) не работает с API драйвера CUDA.
Между API нет заметной разницы в производительности. То, как ваши ядра используют память и как они расположены на GPU (в деформациях и блоках), будет иметь гораздо более выраженный эффект.
Я обнаружил, что для развертывания библиотек в многопоточных приложениях контроль над контекстом CUDA, предоставляемый драйвером API, был критическим. Большинство моих клиентов хотят интегрировать ускорение графического процессора в существующие приложения, и в настоящее время почти все приложения являются многопоточными. Поскольку я не мог гарантировать, что весь код графического процессора будет инициализирован, выполнен и освобожден из одного и того же потока, мне пришлось использовать драйвер API.
Мои первые попытки с различными обходными путями в API времени выполнения привели к сбою, иногда впечатляющим образом - я обнаружил, что могу многократно мгновенно перезагружать машину, выполняя только неправильный набор вызовов CUDA из разных потоков.
Так как мы перенесли все через Driver API, все было хорошо.
J
Пара важных вещей, чтобы отметить:
Во-первых, различия между API относятся только к коду хоста. Ядра точно такие же. на стороне хоста сложность API драйвера довольно тривиальна, фундаментальные различия:
в драйвере API у вас есть доступ к функциональности, которая недоступна в API времени выполнения, как контексты.
эмулятор работает только с кодом, написанным для API времени выполнения.
о, и в настоящее время очень удобная библиотека cudpp работает только с API времени выполнения.
Есть некоторые реальные проблемы с выравниванием аргументов и API драйвера. Проверьте бета-версию CUDA 2.2 (или более позднюю) для получения дополнительной информации.