В моем приложении поток с графическим интерфейсом использует Direct2D для отображения изображений, позволяя пользователю панорамировать и масштабировать, а другой поток использует CUDA для обработки изображений. Чтобы поток обработки изображений не мешал потоку графического интерфейса и чтобы ускорить процесс, было принято решение добавить отдельную графическую карту для вычислений CUDA со следующей настройкой:
- Nvidia Quadro 400 для дисплея (Direct2D, продается вместе с ПК, достаточно для отображения)
- Nvidia GT640 исключительно для вычислений CUDA (добавлен специально для вычислений CUDA, поскольку у него больше ядер и поэтому он более эффективен для того, что должно делать приложение, отключен для отображения в BIOS, экран не подключен). Поток CUDA содержит код, позволяющий использовать только этот GT640.
Однако это не сработало, как ожидалось, так как когда пользователь перемещает изображение, что вызывает несколько обновлений дисплея подряд, время выполнения CUDA подскакивает с типичных 20 мс до примерно 800 мс. Используя GPUView (который я обнаружил при исследовании этой проблемы и вообще не осваиваю), я смог увидеть, что поток CUDA, похоже, ожидает завершения обновления дисплея, прежде чем поставить свои команды в очередь на графический процессор. В то же время, Direct2D большую часть времени оставляет GPU неиспользованным (1 мс работы за 16 мс периода вертикальной синхронизации). Похоже, что мои вызовы Direct2D блокируют все графические процессоры на 16 мс, а затем поток GUI позволяет потоку CUDA голодать (хотя эти потоки не синхронизируются никаким образом, кроме доступа к графическому процессору).
Итак, вопросы:
- Что может происходить?
- Поможет ли заставить Direct2D выполняться только на одном конкретном графическом процессоре?
- Это вообще возможно или я неправильно воспринимаю проблему?