#cuda #buffer #nvidia
#cuda #буфер #nvidia
Вопрос:
Моя программа запускает 2 потока — поток A (для ввода) и B (для обработки). У меня также есть пара указателей на 2 буфера, так что, когда поток A закончит копирование данных в буфер 1, поток B начнет обработку буфера 1, а поток A начнет копирование данных в буфер 2. Затем, когда буфер 2 заполнен, поток A копирует данные в буфер 1, а поток B обрабатывает буфер 2, и так далее.
Моя проблема возникает, когда я пытаюсь поместить буфер cudaMemcpy[] в d_Buffer (который ранее был выделен основным потоком, т. Е. до создания потока. Buffer[] также были заблокированы основным потоком). Я получаю ошибку «недопустимый аргумент», но понятия не имею, какой аргумент является недопустимым.
Я сократил свою программу до однопоточной, но по-прежнему использую 2 буфера. То есть копирование и обработка выполняются друг за другом, а не одновременно. Строка cudaMemcpy в точности совпадает с двухпоточной. Однопоточная программа работает нормально.
Я не уверен, в чем заключается ошибка.
Спасибо.
С уважением, Рейн
Ответ №1:
Если вы делаете это с CUDA 3.2 или более ранней версией, причина в том, что контексты графического процессора привязаны к определенному потоку. Если многопоточная программа выделяет память на одном и том же графическом процессоре из разных потоков хоста, распределение приводит к созданию разных контекстов, и указатели из одного контекста не переносятся в другой контекст. У каждого контекста есть свое собственное «виртуализированное» пространство памяти для работы.
Решение состоит в том, чтобы либо использовать API переноса контекста для передачи одного контекста из потока в поток по мере их выполнения, либо попробовать новую общедоступную версию CUDA 4.0 rc2, которая должна поддерживать то, что вы пытаетесь сделать, без использования переноса контекста. Недостатком является то, что 4.0rc2 является тестовой версией, и для нее требуется определенный драйвер бета-версии. Этот драйвер не будет работать на всем оборудовании (например, ноутбуках).
Комментарии:
1. Спасибо! Я нашел cuCtxPushCurrent и cuCtxPopCurrent, которые являются API-интерфейсами драйверов. Существуют ли API среды выполнения для переноса контекста? Могу ли я смешивать API среды выполнения и драйвера в одной программе?
2. Не существует подпрограмм управления контекстом API среды выполнения, поскольку контексты неявны / абстрагированы в API среды выполнения. Однако, поскольку была выпущена CUDA 3.1, да, вы можете безопасно смешивать вызовы API среды выполнения и драйвера. Вероятно, вам будет проще всего использовать API драйвера для создания контекста и переноса его из потока в поток, а для остальных операций в контексте использовать runtime API. Имейте в виду, что сама по себе контекстная миграция не является бесплатной, она добавляет немного задержки, но это официальный способ сделать то, что вы хотите, до CUDA 4.0
3. Я хочу опробовать CUDA 4.0. Должен ли я просто установить CUDA 4.0 поверх моей текущей установки CUDA 3.2? Нужно ли мне что-либо удалять, например, драйверы и т.д.?