Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пособие_CUDA.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
5.04 Mб
Скачать
      1. Отладка программ в режиме эмуляции устройства

Для ОС Linux предусмотрен специальный отладчик CUDA-GDB, который является расширением стандартного отладчика GDB (GNU Project Debugger) версии 6.6 для платформы i386/AMD64. Он разработан для предоставления разработчику гетерогенной среды отладки, поддерживающей как хостовый код, так и CUDA-код.

Кроме того, компилятор и интерфейс времени выполнения поддерживают режим эмуляции CUDA-устройства, предназначенный для отладки, который может быть использован даже при отсутствии CUDA-совместимого устройства. При компиляции программы в этом режиме (с опцией “–deviceemu”) код CUDA-функций будет скомпилирован для запуска на хосте, позволяя задействовать стандартные инструменты отладки, как в программе, изначально предназначеной для выполнения на хосте. В коде этот режим можно обнаруживать по наличию макроса __DEVICE_EMULATION__.

Существует ограничение: весь код приложения, включая используемые библиотеки, должен быть скомпилирован только в одном из двух режимов: с выполнением на CUDA-устройствах или с их эмуляцией. В противном случае, линковка двух модулей, скомпилированных в обоих режимах, приведет к возникновению ошибки времени выполнения при инициализации: cudaErrorMixedDeviceExecution.

При запуске программы в режиме эмуляции интерфейс времени выполнения будет эмулировать программную модель CUDA. Для каждого потока из связки потоков будет создан отдельный поток на хосте. При этом программист должен убедиться в наличии необходимых ресурсов:

  • возможность хоста запускать максимальное число потоков из одной связки плюс еще один для управляющего потока;

  • достаточный объем свободной памяти (каждый поток получает 256 КБ стека).

В режиме эмуляции предоставляется множество возможностей, что делает его очень эффективным инструментом для отладки. Использование стандартного отладчика дает доступ ко всем его возможностям, таким как установка точек останова (breakpoints) и инспекция данных. В код CUDA-функции можно добавлять участки, не способные выполняться на CUDA-устройстве, такие как операции ввода/вывода для диска и экрана – printf() и т.п. Так как все данные размещаются в памяти хоста, то возможны любые перекрестные вызовы функций и доступ к данным, к примеру, из функций хоста возможен доступ к данным, предназначенным для устройства. В случае некорректного использования встроенной функции барьерной синхронизации среда выполнения регистрирует ситуацию взаимной блокировки (dead lock).

Программисты должны помнить, что режим эмуляции CUDA-устройства не учитывает детали аппаратной реализации. Поэтому его эффективно использовать при нахождении алгоритмических ошибок, но обнаружение ошибок другого типа может быть затруднено. Состояния гонки (race conditions) намного реже проявляются в режиме эмуляции, так как одновременно выполняется меньшее число потоков.

При разыменовании указателя на глобальную память CUDA-устройства, выполняемую на хосте, или указателя на память хоста, выполняемую на CUDA-устройстве, программа в режиме эмуляции приведет к правильному результату, однако выполнение на CUDA-устройстве может вызвать непредсказуемые последствия.

В большинстве случаев одинаковые операции плавающей арифметики дадут отличающиеся результаты на реальном и эмулируемом CUDA-устройстве. Этого следует ожидать и в общем случае, так как результат выполнения этих операций зависит от компилятора, его опций, наборов инструкций и аппаратных архитектур. В частности, некоторые платформы сохраняют промежуточные результаты вычислений с плавающей арифметикой одинарной точности в регистрах с расширенной точностью, что потенциально может привести к значимым различиям точности при использовании режима эмуляции. В этом случае программист может попробовать применить один из следующих приемов:

  • объявить некоторые переменные плавающей арифметики с ключевым словом volatile для принудительного хранения в формате одинарной точности;

  • в компиляторе gcc использовать опцию “-ffloat-store”;

  • в компиляторе Visual C++ использовать опции “/Op” или “/fp”;

CUDA-устройства с вычислительной способностью 1.x не поддерживают денормализованные числа (см. раздел “Appendix G” руководства “CUDA Programming Guide”) для плавающей арифметики одинарной точности, в отличие от типичных хостов. В этом случае на одном CUDA-устройстве операции могут привести к бесконечному результату, а на другом – к конечному. В режиме эмуляции размер варпа равен единице. Следовательно, функции для голосования в варпах дадут отличающиеся результаты. Начиная с версии инструментария CUDA Toolkit 3.0, компания NVIDIA прекратила развитие режима эмуляции в пользу специального инструмента NVIDIA Parallel Nsight.