трассировка лучей с помощью CUDA
-
09-06-2019 - |
Вопрос
В настоящее время я использую raytracer. Поскольку трассировка лучей чрезвычайно сложна для вычислений, и поскольку я все равно буду изучать программирование на CUDA, мне было интересно, есть ли у кого-нибудь опыт объединения этих двух. Я не могу точно сказать, соответствуют ли вычислительные модели, и я хотел бы знать, чего ожидать. У меня складывается впечатление, что это не совсем совпадение на небесах, но приличное увеличение скорости было бы лучше, чем ничего.
Решение
В CUDA следует с большой осторожностью относиться к тому, что расходящийся поток управления в коде вашего ядра абсолютно УБИВАЕТ производительность благодаря структуре базового аппаратного обеспечения графического процессора. Графические процессоры обычно имеют массово параллельные данные рабочие нагрузки с высококогерентным потоком управления (т. Е. У вас есть пара миллионов пикселей, каждый из которых (или, по крайней мере, большие полосы) будет работать с точным тем же шейдерная программа, даже проходящая в одном направлении по всем ветвям, что позволяет им проводить некоторые аппаратные оптимизации, например, иметь только один кэш команд, модуль выборки и логику декодирования для каждой группы из 32 потоков. В идеальном случае это распространенные в графике, они могут транслировать одну и ту же инструкцию всем 32 наборам исполнительных блоков в одном и том же цикле (это называется SIMD или несколько данных с одной инструкцией). Они могут эмулировать MIMD (несколько -Instruction) и SPMD (Single-Program), но когда потоки внутри потокового мультипроцессора (SM) расходятся (отбирают разные пути кода из ветви), логика проблемы фактически переключается между каждым путем кода на циклической основе . Вы можете представить себе, что в худшем случае, когда все потоки находятся на В отдельных направлениях загрузка вашего оборудования снизилась в 32 раза, что фактически убило любую выгоду, которую вы бы получили, работая на GPU через CPU, особенно учитывая издержки, связанные с маршалингом набора данных из CPU, через PCIe, для графический процессор.
Тем не менее, трассировка лучей, в некотором смысле параллельная данным, имеет широко расходящийся поток управления даже для скромно сложных сцен. Даже если вам удастся отобразить пучок плотно расположенных лучей, которые вы выбросили прямо рядом друг с другом, на один и тот же SM, данные и расположение инструкций, которые вы имеете для первоначального отскока, не будут сохраняться очень долго. Например, представьте, что все 32 высоко когерентных луча отражаются от сферы. После этого отскока они все пойдут в совершенно разных направлениях и, вероятно, будут поражать объекты, сделанные из разных материалов, с разными условиями освещения и так далее. Каждый материал и набор условий освещения, окклюзии и т. Д. Имеет свой собственный поток команд, связанный с ним (для вычисления рефракции, отражения, поглощения и т. Д.), И поэтому становится довольно трудно запустить один и тот же поток команд даже в значительной части темы в СМ. Эта проблема, связанная с современным состоянием кода трассировки лучей, снижает использование вашего графического процессора в 16–32 раза, что может сделать производительность неприемлемой для вашего приложения, особенно если оно работает в режиме реального времени (например, в игре). Это все еще может быть лучше, чем процессор, например ферма рендеринга.
В исследовательском сообществе сейчас появляется новый класс ускорителей MIMD или SPMD. Я бы рассматривал их как логические платформы для программного обеспечения, трассировки лучей в реальном времени.
Если вам интересны задействованные алгоритмы и их отображение в коде, посмотрите POVRay. Также посмотрите на фотонное картирование, это интересная техника, которая даже на один шаг ближе к представлению физической реальности, чем трассировка лучей.
Другие советы
Nvidia продемонстрировала трассировщик лучей в CUDA на своей конференции NVision в этом году. Вот ссылка на их слайды об этом.