Page 3 of 17

Re: Оптимизация ядерной графики

Posted: Sun Nov 21, 2010 3:46 pm
by art_zh
Serge wrote:Почесал репу, есть относительно несложный способ ускорить ввод/вывод аппаратной акселерацией при помощи shadowfb. Сейчас ядро отображает первичный видеобуфер на LFB_BASE. Драйвер создаёт в системной памяти текстуру размером в экран и ремапит её вместо видеопамяти. Ставится обработчик прерывания и на обратном ходе луча текстура блиттером копируется в видеопамять. Получаем ускорение на запись в 60 раз и три порядка на чтение (если нет проблем с кешированием). Видеоплеер будет очень рад. В этом случае оптимизация кода отрисовки даст очень хороший прирост.
А как насчет совсем сумасшедшей идеи - сделать много текстур размером с программное окошко (пользовательская область + рамка) каждая, и грузить блиттером только те "текстуры", в которых в течение последнего кадра имело место рисование/перемещение?
Я тут вижу три больших плюса и один огромный минус:

+ приложение просто рисует в своем индивидуальном "фреймбуфере", а ядро только предоставляет ему линейный адрес этого буфера - все остальные инструменты рисования (putpixel, drawline, drawbox ...) могут быть легко реализованы в Круге Третьем без потерь в скорости. И даже с заметным ускорением - не надо будет гонять int40 ради каждой ерунды.

+ программные задержки сокращаются (почти) до теоретического минимума за счет исключения цепочки тупых проверок и перепроверок (перекрытия окон, попаданий в границы экрана, и т.п.), которые сейчас съедают сотни тактов на каждом пикселе.

+ код GUI ядра становится простым как табуретка (во всяком случае, в сравнении с теперешним кошмаром), что должно положительно сказаться не только на скорости и размере, но и на общей надежности ядерных служб, а также на переносимости GUI на новые графические платформы.

- единый системный фреймбуфер сейчас требует максимум 9 Мбайт системной памяти (1920х1200х4). Если у каждого окошка будет свой отдельный фрейм, то системной памяти на всех может не хватить (крайний случай: 256 распахнутых на весь экран окон требуют больше 2Гб).

Re: Оптимизация ядерной графики

Posted: Sun Nov 21, 2010 5:46 pm
by <Lrz>
art_zh
Можно паковать в png изображения (без потери качества) или другой подходящий формат. Количество памяти значительно сократится. Однако, можно использовать такую методику:
1) Активное окно храниться в raw формате, как и последние 5 или 10 открытых окон. Менеджер предсказывает какое из окон может понадобиться пользователю и быстро преобразует png в raw. Конечно, память будет кушать, но все будет зависеть от потребности пользователя.

Re: Оптимизация ядерной графики

Posted: Mon Nov 22, 2010 12:11 am
by Serge
art_zh

Это на будущее. Сначала надо сделать стабильно работающий блиттер.

Re: Оптимизация ядерной графики

Posted: Mon Nov 22, 2010 9:00 pm
by FireWall
Цитата: "Но в любом случае имхо назрел вопрос раздельной компиляции ядра для разных платформ. Так можно снять из ядра 30-40 килобайт ненужного кода и дублирующих проверок. И только так можно обеспечить эффективную работу системы на все более непохожих друг на друга платформах.

Наилучшим вариантом здесь мне видится аналог линуксовского config.h
"

Полностью с этим согласен.

Re: Оптимизация ядерной графики

Posted: Tue Nov 23, 2010 2:16 pm
by art_zh
Похоже, ЭТО всё, что можно выжать из того что есть.

Для горизонтальной/вертикальной линии из N точек число умножений уменьшено с 2N (3N в случае инверсии цвета) до 2, число проверок границ - с 3N до N+3.

Дальнейшее ускорение возможно только если опрокинуть всю оконную графику вверх тормашками, построив ее не на базе PUTPIXEL (как сейчас), а с прицелом на буферизацию GUI с последующей максимально быстрой отрисовкой отдельных окон (см. выше).

Serge
этот подход можно попробовать и без блиттера, с простым копированием отдельных оконных блоков в общий экранный фреймбуфер. Работы здесь прорва, но делать ее когда-нибудь все равно придется.

Re: Оптимизация ядерной графики

Posted: Tue Nov 23, 2010 2:43 pm
by Mario
art_zh
Неплохо было бы видеть результаты полученные от тестирующей программы MGB, при текущем коде и при новом.

Re: Оптимизация ядерной графики

Posted: Tue Nov 23, 2010 6:08 pm
by Serge
art_zh

Две проверки в основном цикле hline.draw на инверсию цвета и edi=1 не есть true coolhacker assembler style. Такой вариант:

Code: Select all

bt ecx, 24
rcl edi, 1
jmp [hline.draw_table+edi*4]

.align 4
hline.draw_table:
dd .draw
dd .draw_negative
dd .draw_forced
dd .draw_forced_negative
Четыре цикла для разных вариантов отрисовки. Заметный выигрыш будет для развёрнутых циклов при отрисовке в системную память. Адреса циклов надо обязательно выровнять.

Re: Оптимизация ядерной графики

Posted: Tue Nov 23, 2010 9:49 pm
by art_zh
Serge

Офигеть! :shock:

P.S. Вообще-то я электронщик, и под кулхацкера никогда не косил. Хотя с вами тут совсем опрограммёришься...

Спасибо, учту!

Re: Оптимизация ядерной графики

Posted: Tue Nov 23, 2010 9:54 pm
by Mario
Ну, мой личный опыт 8 лет радиокружка, плюс 2,5 года Слесарь КИП и Автоматики - какбэ не в счет. :lol:

Re: Оптимизация ядерной графики

Posted: Tue Nov 23, 2010 10:12 pm
by Serge
art_zh

Я подумал что таким образом легко сделать код для разных режимов и расширений команд. Общий код с проверкой координат и отсечением, а дальше вызов или переход на функцию из таблицы с кодом для ALU, MMX, SSE2

Code: Select all

bt ecx, 24
rcl edi, 1
shl edi, 2
add edi, [hline_draw_table]
jmp [edi]
или если есть свободный регистр

Code: Select all

mov reg, [hline_draw_table]
bt ecx, 24
rcl edi, 1
jmp [reg+edi*4]
этом случае [hline_draw_table] хранит заранее установленный адрес одной из таблицы с учётом возможностей процессора.

Re: Оптимизация ядерной графики

Posted: Wed Nov 24, 2010 3:54 am
by art_zh
Сделал, вроде все по-уму получилось.
Замерил бенчмарк и еще раз офигел:

Реально ускорилось (на 20%) только рисование горизонтальных линий. Все остальное - в пределах процента за счет незначительной оптимизации базовой процедуры putpixel.
Конечно, в сисфункции прирост скорости заметен меньше, чем в ядре, но все равно фифект не стоил выделки.
Платформа - та же rs780 с 3.4-гигагерцовым атлоном во главе. На таких моторах на одном умножении много не сэкономишь, особенно если память притормаживает...

Re: Оптимизация ядерной графики

Posted: Wed Nov 24, 2010 5:03 am
by <Lrz>
art_zh
Как проводил замеры? Обычно, проводят 10-20 замеров, получают среднее значение. Разброс не очень велик и по некоторым тестам находится в пределах погрешности измерений.

Re: Оптимизация ядерной графики

Posted: Wed Nov 24, 2010 10:58 am
by Mario
art_zh
Не переживай, так достаточно часто бывает - оптимизируешь, а в результате прироста нет.
Основные тормоза возникают на делении, даже больше чем на умножении.

Re: Оптимизация ядерной графики

Posted: Wed Nov 24, 2010 1:03 pm
by art_zh
<Lrz>
На скриншоте конечно - два типичных измерения. Повторные замеры пляшут плюс-минус полкопейки.
Усреднять и вычислять дисперсию особого резона не было - эффект и в самом деле чуть выше погрешностей.
На старых CPU разница должна быть более заметна, но у меня сейчас VESA-графика допилена только для ядра-А (Атлон64 и выше), проверить не на чем.

Mario
Да я особенно и не переживаю, хуже-то ведь не стало :wink:
И тот факт, что современные монстры научились разгрызать целочисленное умножение за 2-3 такта, вовсе не означает, что оптимизация стала совсем бесполезной.
Так или иначе, для сложения требуется переключить несколько десятков вентилей, а для умножения - несколько сотен. Пусть два процесса занимают одно и то же время, но в первом случае будет потребляться значительно меньшая мощность - это реальная и нужная оптимизация.

Меня совсем другое заинтересовало: почему горизонтальная линия рисуется с такой дикой скоростью (100Мпикс/с) - в 15 раз быстрее, чем аналогичная по алгоритму вертикальная?

Насколько я помню, фреймбуфер у нас не кэшируется, и ему должно быть фиолетово, как в него пишутся пиксели - по строчкам или по столбцам.
Так что причина может сидеть только в проверке экранной карты [_WinMapAddress], в которой для каждой точки на экране прописана её оконная принадлежность.

имхо, кэшировать экранную карту - это клинический идиотизм. Никакого прироста в рисовании это не дает (разве что для длинных горизонтальных линий), зато регулярно ломает стэк ядра и программ. И чем шире экран - тем хуже общая производительность системы.

Re: Оптимизация ядерной графики

Posted: Wed Nov 24, 2010 1:14 pm
by Mario
art_zh wrote: Меня совсем другое заинтересовало: почему горизонтальная линия рисуется с такой дикой скоростью (100Мпикс/с) - в 15 раз быстрее, чем аналогичная по алгоритму вертикальная?
Ну, хотя бы потому что горизонтальная это запись последовательных соседних ячеек, а вертикальная это таки выборка произвольных. Контроллер памяти имхо так работает.