Войти
ПрограммированиеФорумГрафика

Оптимизация. Как еще улучшить внутренние циклы? Масштабирование CSR-спрайтов (4 стр)

Страницы: 13 4 5 616 Следующая »
#45
13:12, 26 сен 2022

MrShoor
> по мудацки было делать, чтобы операция присвоения возврващала ссылку
в си были распространены конструкции инициализации вида

int x, y, z;
x = y = z = 0;
#46
13:16, 26 сен 2022

SereG
> Почему, очень удобно:
>
> if (Unit* unit = dynamic_cast<Unit*>(obj))
> {
> unit->...
> }
А это пример мудацкого кода, который ничего бы не потерял, если бы был написан так:

Unit* unit = dynamic_cast<Unit*>(obj)
if (unit)
{
  unit->...
}

#!
> int x, y, z;
> x = y = z = 0;
И еще один пример мудацкого кода.

#47
15:25, 26 сен 2022

MrShoor
> А это пример мудацкого кода, который ничего бы не потерял, если бы был написан так:
> Unit* unit = dynamic_cast<Unit*>(obj)
> if (unit)
> {
> unit->...
> }

Лишние фигурные скобки.

for (auto obj : objects)
  if (Unit* unit = dynamic_cast<Unit*>(obj))
    unit->...

#48
15:42, 26 сен 2022

SereG
> Лишние фигурные скобки.
>
> for (auto obj : objects)
> if (Unit* unit = dynamic_cast<Unit*>(obj))
> unit->...
О, и еще один пример мудацкого кода. Безотносительно возможности присваивать внутри if-а можно было написать:

for (auto obj : objects) {
    if (foo) {
        bar...
    }
}

Но нет, написано по мудацки без фигурных скобок. Это же так тяжело, нажать пару клавиш.

#49
18:46, 26 сен 2022

MrShoor
> Шо там, уже можно писать hlsl в jetbrains?
В райдере можно, но не проверял, подчеркнет ли.
И вообще, речь же шла не о шейдерных языках. Я такой код видел в c++/c#.

#50
(Правка: 21:38) 21:10, 26 сен 2022

В жирном if продублирован последний or.

#51
(Правка: 2:08) 0:40, 27 сен 2022

entryway, спасибо, что заметили! Подправлю в первом посте только это место. Чтобы видеть потом разницу с уже оптимизированным вариантом. А более оптимизированный на данный момент вариант такой:

+ Показать
#52
(Правка: 0:58) 0:43, 27 сен 2022

Скрины производительности:

+ Показать

  Оптимизации вроде пустяковые, но почти 22 % разницы.
  Какие еще проблемные места вижу. Взятие целой части в math-модуле стандартной runtime-библиотеки имеет довольно таки длинный код(с у четом того, что эта операция берется каждый пиксель, ну или каждый "нечетный", если брать более мелкие уровни масштабирования):

+ Показать

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

(PRGBA(bmp_bkgnd_ptr2+1)^.r+(s1_*(PRGBA(nt_pix_intr_ccl_arr_ptr)^.r-PRGBA(bmp_bkgnd_ptr2+1)^.r))>>16)<<00+
(PRGBA(bmp_bkgnd_ptr2+1)^.g+(s1_*(PRGBA(nt_pix_intr_ccl_arr_ptr)^.g-PRGBA(bmp_bkgnd_ptr2+1)^.g))>>16)<<08+
(PRGBA(bmp_bkgnd_ptr2+1)^.b+(s1_*(PRGBA(nt_pix_intr_ccl_arr_ptr)^.b-PRGBA(bmp_bkgnd_ptr2+1)^.b))>>16)<<16;

Но это уже конечно на будущее.

#53
0:56, 27 сен 2022

P.S. Как уже заметил товарищ Skvoznjak, строки с множеством нулей и подобные "извращения" служат для более удобного мультистрочного редактирования в случае чего, типа так:
MultiRow_Edit | Оптимизация. Как еще улучшить внутренние циклы? Масштабирование CSR-спрайтов

#54
2:39, 27 сен 2022

ArtProg
> Trunc
ты уверен что они тебе нужны? Ты знаешь сколько это времени занимает? Особенно в цикле.

#55
(Правка: 3:27) 3:01, 27 сен 2022

  Ызкшеуы_Optimized_WithoutTrunc | Оптимизация. Как еще улучшить внутренние циклы? Масштабирование CSR-спрайтов
  Это если вобще удалить строки во внутренних циклах с целыми частями. То есть какая-то альтернатива все-таки нужна, иначе последующие вычисления будут некорректны. В самом первом, совсем неоптимизированном, варианте в последнем внутреннем цикле их было 8. Они нужны, чтобы избавиться от чисел с плавающей точкой. Это я еще просто откинул ветки, которые считали площади частей оригинального пикселя, попадающих на два нижних пикселя приемника и без них качество почти не пострадало. Но дальше уже шло существенное ухудшение качества, вплоть до того, что проще уже было использовать самый первый цикл(тот, что повыше кучи if-ов). На этом идеи пока что кончились. Не отказался бы даже от ассемблерного варианта для взятия целой части.
  UPD. Появилась еще одна идея насчет упрощения функции Trunc. Поскольку, как нетрудно показать, что

alpha_inv_mul_s10000*s0<65536=2^16

и

alpha_inv_mul_s10000*s1<65536=2^16

, причем sup A-inf A<2^15(проверял только для 0.25<=scale multiplier.x<0.75 и 0.25<=scale multiplier.y<0.75 одновременно), где A - множество аргументов, то может быть возможно изготовить специальную, с учетом такого множества A, lookup table с каким нибудь шагом. Надо еще подумать над этим вобщем.

#56
3:27, 27 сен 2022

попробуй вместо Trunc подставить (- 0.5) в формулы. Может прокатить.

#57
3:47, 27 сен 2022

  Увы, но так тоже глючит

+ Показать

  Правда без целой части кажется также не обойтись(если конечно правильно посчитал):

                     (bmp_bkgnd_ptr2+000000000000000+1)^:=Trunc((PRGBA(bmp_bkgnd_ptr2+1)^.r+(-0.5{s1_}*(PRGBA(nt_pix_intr_ccl_arr_ptr)^.r-PRGBA(bmp_bkgnd_ptr2+1)^.r))/65536{>>16})      {<<00}+
                                                                (PRGBA(bmp_bkgnd_ptr2+1)^.g+(-0.5{s1_}*(PRGBA(nt_pix_intr_ccl_arr_ptr)^.g-PRGBA(bmp_bkgnd_ptr2+1)^.g))/65536{>>16})*256  {<<08}+
                                                                (PRGBA(bmp_bkgnd_ptr2+1)^.b+(-0.5{s1_}*(PRGBA(nt_pix_intr_ccl_arr_ptr)^.b-PRGBA(bmp_bkgnd_ptr2+1)^.b))/65536{>>16})*65536{<<16});
#58
(Правка: 4:25) 4:22, 27 сен 2022

если у тебя цель — поупражняться в CPU-рендеринге в качестве хобби, то здорово, флаг в руки, барабан на шею. только не надо придумывать оправдания, почему это может иметь реальный практический смысл. твоя текущая гига-оптимизированная версия рендерит 1000 спрайтов за 280ms. GPU твою тысячу спрайтов отрендерит за время, которое ты даже нормально измерить не сможешь, потому что оно будет меньше погрешности измерения. архитектура gpu специально спроектирована для таких задач и она с ними справляется несравнимо быстрее cpu(не в полтора или два раза, а в тысячи раз) вообще без каких бы то ни было оптимизаций. объективно если тебе хочется реализовать самый быстрый в мире растеризатор, то начинать надо с брутфорсного gpu растеризатора и оптимизировать дальше оттуда.

#59
(Правка: 4:28) 4:25, 27 сен 2022

  А в платформерах оно нужно - большее количество спрайтов?
  Насчет GPU у меня есть свои соображения, но пока не закончу с софтачом, врядли перейду на GPU. В крайнем случае многопоточка.

Страницы: 13 4 5 616 Следующая »
ПрограммированиеФорумГрафика