cudaMemcpy неверный аргумент

Моя программа запускает 2 потока - Thread A (для ввода) и B (для обработки). У меня также есть пара указателей на 2 буфера, так что, когда поток A закончит копирование данных в буфер 1, поток B начнет обработку буфера 1, а поток A начнет копирование данных в буфер 2. Затем, когда буфер 2 заполнен, поток A копирует данные в буфер 1, а поток B обрабатывает буфер 2 и т. д.

Моя проблема возникает, когда я пытаюсь преобразовать cudaMemcpy Buffer[] в d_Buffer (который ранее был cudaMalloc'd основным потоком, т.е. до создания потока. Buffer[] также был malloc'd основным потоком). Я получаю сообщение об ошибке "недопустимый аргумент", но не знаю, какой аргумент является недопустимым.

Я сократил свою программу до однопоточной программы, но все еще использую 2 буфера. То есть копирование и обработка происходят друг за другом, а не одновременно. Строка cudaMemcpy точно такая же, как и двухпоточная. Однопоточная программа работает нормально.

Я не уверен, где ошибка.

Спасибо.

С уважением, Рейн


person Rayne    schedule 11.04.2011    source источник


Ответы (1)


Если вы делаете это с CUDA 3.2 или более ранней версии, причина в том, что контексты графического процессора привязаны к определенному потоку. Если многопоточная программа выделяет память на одном и том же графическом процессоре из разных потоков хоста, выделение завершается созданием разных контекстов, а указатели из одного контекста не переносятся в другой контекст. Каждый контекст имеет свое собственное «виртуализированное» пространство памяти для работы.

Решение состоит в том, чтобы либо использовать API миграции контекста для передачи одного контекста из потока в поток по мере их работы, либо попробовать новую общедоступную версию CUDA 4.0rc2, которая должна поддерживать то, что вы пытаетесь сделать без использования миграции контекста. Недостатком является то, что 4.0rc2 является тестовой версией, и для нее требуется специальный драйвер бета-версии. Этот драйвер не будет работать со всем оборудованием (например, с ноутбуками).

person talonmies    schedule 11.04.2011
comment
Спасибо! Я нашел cuCtxPushCurrent и cuCtxPopCurrent, которые являются API-интерфейсами драйверов. Существуют ли API среды выполнения для переноса контекста? Можно ли смешивать API среды выполнения и драйвера в одной программе? - person Rayne; 11.04.2011
comment
Подпрограммы управления контекстом API среды выполнения отсутствуют, поскольку контексты неявно/абстрагируются в API среды выполнения. Однако с момента выпуска CUDA 3.1 да, вы можете безопасно смешивать вызовы API среды выполнения и драйвера. Возможно, вам будет проще всего использовать API-интерфейс драйвера для создания контекста и переноса его из потока в поток, а для остальных операций в контексте использовать API-интерфейс времени выполнения. Имейте в виду, что миграция контекста сама по себе не бесплатна, она немного увеличивает задержку, но это официальный способ сделать то, что вы хотите до CUDA 4.0. - person talonmies; 11.04.2011
comment
Я хочу попробовать CUDA 4.0. Нужно ли просто установить CUDA 4.0 поверх моей текущей установки CUDA 3.2? Мне нужно будет удалить что-нибудь, например. драйвера и тд? - person Rayne; 12.04.2011