Почему инициализация графического процессора занимает очень много времени на архитектуре Kepler и как это исправить?
При запуске моего приложения самая первая cuda_malloc занимает 40 секунд, что связано с инициализацией графического процессора. Когда я работаю в режиме отладки, это сокращается до 5 секунд, а когда я запускаю тот же код на устройстве Fermi, это занимает гораздо меньше секунды (в моем случае это даже не стоит измерять).
Самое смешное, что если я скомпилирую для этой конкретной архитектуры, используя флаг sm35 вместо sm20, он снова станет быстрым. Поскольку я пока не должен использовать какие-либо новые функции sm35, как я могу скомпилировать для sm20 и не иметь такой большой задержки? Также мне любопытно, что вызывает эту задержку? Машинный код перекомпилируется на лету в код sm35?
Ps. Я бегу на Windows, но мой коллега столкнулся с той же проблемой, вероятно, на Windows. Устройство Kepler, версия драйвера 320.
1 ответ
Да, машинный код перекомпилируется на лету. Это называется этапом JIT-компиляции, и он будет происходить каждый раз, когда машинный код не соответствует используемому устройству (и при условии, что в исполняемом файле существует допустимый код PTX).
Вы можете узнать больше о JIT-компиляции здесь. Обратите внимание на обсуждение кеша, который должен облегчить проблему после первого запуска.
Если вы укажете компиляцию для sm_20 и sm_35, вы можете создать двоичный / исполняемый файл, который будет работать быстро на обоих типах устройств, и вы также получите уведомление, если вы используете функцию sm_35, которая не поддерживается в sm_20 (во время компиляции процесс).