вторник, 27 октября 2009 г.

HD 2400 is slow

В общем провёл я предварительные тесты на производительность. Конкретно для Radeon HD 2400 результаты неутешительные - скорость падает приблизительно линейно с возрастанием кол-ва треугольников... Если для квада из двух треугольников получается ~100 fps, то для кубика из 12 треугольников - 20 fps. Для двух кубиков - 11... Скорость мало зависит от площади кадра, которую покрывают кубики, и от типа кушаемых данных - вещественные или байты, хотя при вещественных скорость снижается.

Понятно, откуда линейное падение скорости - от линейного увеличения длины цикла. Я не считал точно, но на глазок длина цикла ~60 инструкций (весь шейдер - 120). 24 треугольника требуют выполнить ~1440 + 60 = ~1500 инструкций. Боттлнек в недостатке вычислительной способности при тупом переборе циклом. Можно взять high-end видеокарту, но это только отодвинет верхнюю границу, после которой симптомы будут аналогичны.

В принципе результаты не так уж плохи (в расчёте на high-end), таким способом можно рассчитывать на возможность играться с несколькими десятками треугольников (мне нужно даже меньше). К тому же на HD 2400 динамический бранчинг нифига не фурычит, а только просаживает скорость :( Хотя очевидно, что он должен давать прирост, например, при cull-инге back-faced треугольников. На нормальном железе с нормальным бранчингом должен быть заметный выигрыш.

Очевидный резерв для таких забав на растеризаторах - использование какого-нить иерархического дерева для геометрии, с обязательным условием, что динамический бранчинг работает эффективно. Это позволит снизить кол-во вычислений, связанных с тестом на пересечение луча и геометрии, правда, появятся затраты на обход дерева. Честно говоря, мне сложно представить, как это можно впихнуть в пиксельный шейдер, и стоит ли - очень быстро всё равно не получится.

Вот как-то так. Но всё же я надеялся на чуть лучшие результаты.

PS. Ну, а что можно сделать с несколькими треугольниками? Поверьте, в умелых руках - очень многое :)

PPS. Вот перед сном думал, как можно ускорить.
1) Я делаю рэйкастинг для всех пикселей фреймбуфера, очевидно что это худший случай. Рэйкастинг - это потому что простейшая реализация. Для рэйтрейсинга легче. Если у нас есть рефрактор, не занимающий всю площадь экрана, то растеризатором сначала рисуем front-faced треугольники, а потом выполняем рэйтрейсинг.
2) Early stencil rejection. Делаем рэйтрейсинг в малю-ю-юсенький render target, разблуриваем получившуюся маску, "натягиваем" её на фреймбуфер и помечаем в стенсиле. Затем делаем нормальный рэйтрейсинг, стенсил тест отбрасывает ненужные фрагменты вне маски.
3) Почему-то подумалось об oct-tree со сферами, описывающими кубики-узлы. Тест на пересечение со сферой тривиален.

Комментариев нет:

Отправить комментарий