Может ли объединенная память CUDA быть записана другим потоком процессора?
Я пишу программу, которая получает изображения с камеры и обрабатывает их с помощью CUDA. Чтобы добиться максимальной производительности, я передаю объединенный буфер памяти CUDA в библиотеку сбора изображений, которая записывает данные в буфер в другом потоке.
Это приводит к всевозможным странным результатам, когда программирование зависает в коде библиотеки, к которому у меня нет доступа. Если я использую обычный буфер памяти и затем копирую в CUDA, проблема исправлена. Поэтому у меня возникло подозрение, что запись из другого потока может быть запрещена, и, как и я, погуглил, я не смог найти однозначного ответа.
Так разрешен ли доступ к унифицированному буферу памяти из другого потока ЦП?
1 ответ
Не должно быть проблем с записью в единый буфер памяти из нескольких потоков.
Однако имейте в виду ограничения, налагаемые, когда concurrentManagedAccess
свойство устройства не соответствует действительности. В этом случае, когда у вас есть управляемый буфер, и вы запускаете ядро, никакой доступ к потоку ЦП / хосту любого типа не разрешается, к этому буферу или любому другому управляемому буферу, пока вы не выполните cudaDeviceSynchronize()
после вызова ядра.
В многопоточной среде это может потребовать определенных усилий.
Я думаю, что это похоже на этот концерт, если это также ваша публикация. Обратите внимание, что для TX2 это свойство должно иметь значение false.
Обратите внимание, что это общее правило в не параллельном случае может быть изменено путем осторожного использования потоков. Однако ограничения по-прежнему применяются к буферам, прикрепленным к потокам, в которых запущено ядро (или к буферам, явно не привязанным к какому-либо потоку): когда указанное выше свойство имеет значение false, доступ к любому потоку ЦП невозможен.
Мотивация такого поведения примерно следующая. Среда выполнения CUDA не знает взаимосвязи между управляемыми буферами, независимо от того, где эти буферы были созданы. Буфер, созданный в одном потоке, может легко содержать объекты со встроенными указателями, и ничто не мешает указателям указывать на данные в другом управляемом буфере. Даже буфер, который был создан позже. Даже буфер, который был создан в другом потоке. Безопасное предположение состоит в том, что любые связи могут быть возможными, и, следовательно, без каких-либо других согласований подсистема управляемой памяти во время выполнения CUDA должна перемещать все управляемые буферы в графический процессор при запуске ядра. Это делает все управляемые буферы без исключения недоступными для потоков ЦП (любой поток, где угодно). В обычном потоке программы доступ восстанавливается при следующем вызове cudaDeviceSynchronize (). Как только поток ЦП, который выдает этот вызов, завершает вызов и продолжает работу, управляемые буферы снова становятся видимыми (всем) потокам ЦП. Другой запуск ядра (где угодно) повторяет процесс и прерывает доступ. Повторим, это механизм, который действует, когда concurrentManagedAccess
свойство на GPU не соответствует действительности, и это поведение может быть несколько изменено с помощью вышеупомянутого механизма присоединения потока.