Ычан: [d | b / bro / hr / l / m / mi / mu / o / ph / r / s / sci / tran / tu / tv / x | es / vg | au / tr | a / aa / c / fi / jp / rm / tan / to / vn / vo]
[Назад] [Вся нить] [Первые 100 сообщений] [Последние 50 сообщений]
Ответ в нить [Последние 50 сообщений]
Имя
Animapcha image [@] [?]
Тема   ( ответ в 9999)
Сообщение flower
Файл 
Пароль  (для удаления файлов и сообщений)
Параметры   
  • Прежде чем постить, ознакомьтесь с правилами.
  • Поддерживаются файлы типов 7Z, BZ, BZ2, GIF, GZ, JPG, MO, MP3, MP4, OGG, OGV, PDF, PNG, PSD, RAR, SVG, SWF, TXT, WEBM, XCF, ZIP размером до 5000 кБ.
  • Ныне 3467 unique user posts. Посмотреть каталог
  • Максимальное количество бампов нити: 500
137217704530.jpg-(251.35KB, 810×810, 7118cd632eddd22b7a4b6559bff5e2fa.jpg)
9999
No. 9999    
http://sourceforge.net/projects/rr-rr/
Предыдущий тред: >>4274
94 сообщений пропущено. Показаны 50 последних сообщений Развернуть все изображения
No. 13229    
144390631514.jpg-(297.38KB, 567×800, b5ffb94b33bd494380072e8b439b4348.jpg)
13229
Сделал интерполяцию строк в скриптах, т. е.
> format "цепочка длины {n} (R = {dist})"
вместо
> format("цепочка длины {0} (R = {1})", n, dist)
или
> "цепочка длины " .. n .. " (R = " .. dist .. ")".
No. 13243    
>>13229
>интерполяцию
значение знаешь?
No. 13244    
Алсо, это твой рисунок последний? Ты нехило так продвинулся, мож ну его этот кодинг, иди лучше хентай рисуй.
No. 13251    
>>13243
https://en.wikipedia.org/wiki/String_interpolation же.
No. 13252    
>>13251
А, спасибо, не знал что это так называется. Термин дурацкий все-таки, при чем тут интерполяция?
No. 13253    
>>13252
Не термин дурацкий, а восприятие у тебя дурацкое. Весь мир несколько десятков лет использует это слово и всем норм.
No. 13254    
>>13253
Извини, что задел твои чувства, братан, но я программирую десятилетиями и слышу это словосочетание впервые. И оно не имеет ни малейшего отношения к интерполяции, поэтому оно дурацкое. Там же в вики приведены нормальные аналоги - подстановка переменных и раскрытие переменных. Сразу понятно, о чем идет речь.
No. 13256    
Удваиваю, это всегда называлось шаблонированием, а интерполяция - это вычисление промежуточных значений между известными.
No. 13259    
>>13252
Интерполяция означает, что в рантайме вычисляется "содержимое" строковой переменной.
http://perlmeme.org/howtos/using_perl/interpolation.html
Во всяком случае, это то, про что статья >>13251. К обработке строк это никакой причастности не имеет, поскольку идет речь именно про распихивание байтов внутри кода во время выполнения программы.
No. 14172    
> Last Update: 20 hours ago
Сидит в крысу пилит, а тред забросил, гад.
No. 15149    
148047253655.gif-(6.69MB, 640×376, ReadDirectoryChanges.gif)
15149
Когда прочитал про ReadDirectoryChanges.
No. 15181    
148087286242.jpg-(160.35KB, 664×768, 1342459081764.jpg)
15181
Анон, я уже довольно долго наблюдаю за твоим проектом, с периодичностью в 3-4 месяца забывая про него, и вспоминая снова.

Расскажи, пожалуйста, вот что. Откуда ты черпаешь информацию по правильному применению OpenGL? Я сам разработчик, немного пытающийся в игродев. Вот только с гл, по всей видимости, без бутылки не разберешься. То-есть, я знаю всю базовую функциональность: шейдеры/вершинные массивы/индексы/состояния, но нету абсолютно представления, как рендерить сложные сцены, а все попытки попробовать кончаются как гроб, кладбище, лаги, ноль кадров в секунду. Мне кажется я упускаю что-то. Может, посоветуешь что-то почитать из книг, или подскажешь правильный вектор гуглинга?
No. 15188    
14809469241.jpg-(1.44MB, 1181×1748, 6a9f80e2550288b094a14ef14be8b053.jpg)
15188
>>15181
Оно не «правильное», я до сих пор не могу UBO и окклюжн запилить :(

Очень сильно не должно тормозить, если только ты какую-нибудь глупость не делаешь, типа пересоздания/перезаливки ресурсов каждый кадр, или Get*/Finish. Посмотри в профилировщике, откуда именно лаги. Если действительно OGL, отсечения должны помочь. По фрустуму легко отсекается под 3/4 (в предположении, что вид от первого лица, угол обзора 90°, а сверху-снизу ничего нет), окклюжн в закрытых пространствах должен отсекать вообще почти всё, но он сложнее.
No. 15189    
>>9999
А с чего ты вообще начинал, Стив?
No. 15190    
>>9999
То есть, ты студент? Чем по жизни занимаешься? Как у тебя вообще ЧТО-ТО выходит? Если не затруднят вопросы, ответь, пожалуйста.
No. 15191    
14810216033.png-(560.45KB, 750×750, efc185a092d69e0dc67ecf84ef087bd9.png)
15191
>>15190
Я крутой хикки! (Поэтому делать нечего.)
И у меня не выходит...

И я бы к этому ТАК не относился. Я с ужасом осознаю, что отношусь к некой немногочисленной, но прослеживающейся категории людей (специально не искал: раз http://freepascal.ru/forum/viewtopic.php?t=10058, два http://spaceway.1gb.ru/, три http://www.gamedev.ru/projects/forum/?id=140784), которые, значит, решают запилить некий «сложный» (нет) проект на Паскале, но при этом:

а) не имеют представления о базовых вещах. Первый в конце треда на полном серьёзе говорит о формировании финальной картинки из нескольких не как о чём-то самом собой разумеющемся, у третьего вообще какая-то непортируемая жесть, которая сегфолтится при любых сценариях использования, отличных от тривиальных, и куда «Lua-ссылки» добавлены автор сам не понимает зачем (в доке так и сказал... «я не так часто пользуюсь Lua», ну просто лол, оно и видно). Да достаточно на исходники взглянуть. Второй их закрыл, но там было хуже первого и третьего вместе взятых, что-то уровня глБегин с шейдерами. (Некрасиво с моей стороны, да, пацаны в лицо говорят. Пофиг.)

б) ввиду (а), а также сломанности самого языка (отчасти — RTL), у них получается многословная и неповоротливая система, нет, груда плоти, которая кровоточит и кричит «убей меня» (aka «перепиши на C#», как Game Maker). Иногда её тянут и иногда она всё же выезжает, чисто экстенсивно, как Castle Engine. Но, как по мне, в проектах на других языках относительная доля треша всё же поменьше 100%.

Вооот. Не то чтобы я собирался свой проект переписывать, но как-то это всё неправильно. :(
No. 15207    
>>15191
>Я крутой хикки! (Поэтому делать нечего.)
Но образование есть какое-нибудь?
No. 15211    
>>15188
А чем можно профилировать эффективно? Вот есть стрейтфорвард вей, установить swap-интервал в 0 и засечь количество кадров в секунду, например. Но это измерение в попугаях. Прочитав твое сообщение, погуглил и наткнулся на apitrace. Весьма неплохо, показывает состояния, полный трейс вызовов gl*, но это все равно не дает понятия о том, где происходит потеря производительности. Такое ощущение, что где-то провал в софтварный режим. У меня Intel HD4000, но что меня смущает, это то, что даже ААА-игры более-менее сносно работают, не проваливаясь никуда.

Что имею конкретно: пытался прикрутить к контексту рендеринг текста. Был взял FT2, и для каждого требуемого символа загружена текстура и создан дисплейный лист (glNewList) с прямоугольником. Далее происходит биндинг требуемой текстуры, вызов нужного листа, перенос матрицы отображения, всё. На мой взгляд, простейшие операции, но стоит выйти за сотню рендеримых прямоугольников, так количество попугаев падает до нуля. Я даже выкинул другие изменения состояний из цикла вывода, но это не изменило ничего. Неужели это так и должно происходить? Что тогда делают в топовых игорях, чтобы держать частоту кадров на уровне, не понимаю?
No. 15214    
148133635299.gif-(80.10KB, 384×256, trebuc.gif)
15214
>>15211
Склей все буквы в один текстурный атлас (у меня прям весь из себя динамический ←>>10485, но если не выделываться, то проще и надёжнее единожды сгенерировать и забыть) и рисуй текст моделью из N квадратиков, вырезающих нужные буквы текстурными координатами. Оптом дешевле, это очень общий принцип. Не используй glNewList, он мог бы быть полезной штукой (коль скоро что-то похожее, буферы команд, есть на низком уровне), но на деле давно убран из спецификации. Листы < ничего (glDraw*) < VBO (glDraw* под glBindBuffer).

>>15207
https://vk.cc/5WSQTW

Раз уж такое дело, я хотел за начало декабря запилить
1) нескучные MIDI-с-изменяемыми-параметрами (т. е. каждый раз у конкретной песенки подкручивается скорость или октава, что как бы превращает её в несколько) — в принципе, это должно свестись к (BASS_MIDI_)StreamGetEvents + <шаманство над MIDI-дорожкой> + StreamSetEvents

2) сделать нормальный парсер шейдеров (очень бы пригодился для человеческого синтаксиса всего, что я там нагородил, и вытаскивания метаинформации вроде используемых юниформов, например, чтобы автоматически подставить вместо них layout(shared) UBO) — можно слизать у https://github.com/graphitemaster/glsl-parser

3) переделать пространственные деревья (а они просто глючат) — этих ребят хочу заставить самих переразбивать себя, когда посчитают нужными

но сделал только, э, подзадачу (1) остальное как-нибудь в январе, ладно?)): теперь, короче, музыка (и звуки) работают в отдельном потоке, вернее, на таймерах, подсел на это дерьмо (ранее я и освобождение ресурсов по таймауту на них переписал). Зачем: чтобы не требовать дёргать BGM.Process(DeltaTime) в «основном цикле», которого может вообще не быть. Что именно происходит: во-первых, с началом воспроизведения песенки плеер взводит на оставшееся время таймер поставить новую, во-вторых, можно начать воспроизводить звук (или сказать ему фейдаутнуться) и забыть о нём, освободив все ссылки — на время воспроизведения звук доверит одну таймеру и тот освободит её, когда звук довоспроизводится/дофейдаутится (избегая немедленной остановки в деструкторе).
No. 15215    
>>15214
Это получается, что на каждый текстовый объект проще сгенерировать массив вершин? Что делать, если текст динамический? При изменении перезагружать вершины? Звучит сомнительно, но я попробую.
Что до текстурного атласа - получается, что набор символов должен быть известен заранее. А если это нет возможности узнать, то как быть?
Ну и возвращаясь к идее более сложных сцен. Допустим, что текст можно попытаться уложить в один-два объекта. Но если, не дай боже, нужно будет рендерить различные модельки с различными текстурами? Их же не склеишь в одну большую модель и текстуру.
No. 15216    
148140143474.jpg-(81.07KB, 480×640, 24577265.jpg)
15216
>>15215
В варианте с матрицами ты, заливая по 16 чисел на символ, косвенно делаешь то же самое, а ведь они на такое даже не рассчитаны! (против потока вершин, даже usage-подсказки в glBufferData завезли).
Чисто ради самоуспокоения спроси у своего шрифта количество символов и нарисуй их все =3.

Один дип на модельку — нормально, их ведь так и делают, с развёртками, вот этим всем. Одномоментно видимых вблизи много не будет. Невидимые рисовать не нужно. Вдали можно рисовать спустя рукава (импостером etc.).
No. 15347    
>>9999
Уважаемый, ты там с голоду умер?
No. 15388    
148378933818.jpg-(137.49KB, 1188×791, QUALITY_7.jpg)
15388
>>9999
Ответь же!
No. 15465    
Где предыдущий тред? Совус, заяем удалил?
Объясните же уже, что это такое-то, блдажд, о чём тред!
No. 15493    
14847808827.gif-(32.35KB, 330×194, ship.gif)
15493
>>15347
Нормалфаги под кроватью пытаются отбирать еду, но они тупые, легко обхитрить. Сделал двухминутное кинцо, зацени: https://github.com/runewalsh/rox-loh/releases/download/v1.0/rox.rar. Это было в меру бесполезно, но по крайней мере понял, как нужно было работать с окном и GL-контекстом — потом как-нибудь перенесу реализацию в основной движок.
No. 15574    
>>15493
Целый месяц еду отбивал?
No. 15616    
148596215790.jpg-(293.10KB, 744×908, 26152978_p0.jpg)
15616
Ой дебил, навелосипедил тогда слежение за звуками, которые закончили воспроизведение, закончили фейдаутиться, etc., а мог бы просто дочитать документацию до возможности установить коллбэки на эти события. То же касается и MIDI: можно, конечно, патчить треки при загрузке, но официально одобренный способ >«подкрутить скорость или высоту» — хукнуть и перекрывать на лету соответствующие MIDI-события (TEMPO/PITCH/etc.). Завтра переделаю (от велосипеда останется одна блокировка).
No. 16218    
14929689979.gif-(816.89KB, 700×500, qwe.gif)
16218
Попробовал переписать пространственные деревья: моя реализация от 2k11 слегка глючила и требовала вызывать перестроение явно, а теперь решил для каждого узла вести учёт ИСКАЖЕНИЙ (красные прогрессбары толщиной в пиксель), и по превышении порога искажённости перестраивать автоматически. По части глюков получилось ещё хуже прежних, вплоть до неработоспособности. На гифке-то всё в порядке, но вот на реальной сцене... Нужно ковырять. Например, записать последовательности операций с деревом, приводящие к «невозможным» результатам, и плясать от них. Эх, вот я криворучка.

С этим условный фейл, а вот MIDI доделал.
No. 16286    
>>16218
Красивая гифка.
No. 16349    
>>16218
Я не понял, математические деревья ты имеешь в виду или реальные, потому что на гифке как будто программа для моделирования сада. Сам хотел такую написать.
No. 17390    
Бамп, хотелось бы апдейтов. Продолжай пилить, ну.
No. 19389    
Что-то застряла разработка. А сф теперь при скачке говорит: malware detected, download at your own risk. Это что же получается?
No. 19390    
>>19389
ОП взял твои деньги и свалил в Мексику.
No. 19393    
152095217856.png-(475.92KB, 800×1067, 67132246_p0.png)
19393
>>19389
Всё не могу себя заставить ту Сырну дорисовать. Ничего, уже вот-вот, сейчас всё будет, ещё немного, ух. шёл 2018

Мальварь, по-видимому, детектится из-за того, что скомпилированный FPC бинарник зачем-то импортирует ReadProcessMemory. Возможно, стоило бы посмотреть, зачем именно, и репортнуть на багтрекер, но вот, скажем, у меня похожая проблема с PyInstaller, и их позиция — не подстраиваться под антивирусы (https://github.com/pyinstaller/pyinstaller/issues/680), что в идеологическом смысле правильно:
>The only correct way to deal with antivirus is to report them that they are wrong. If we are working around them, we simply start a cat-and-mouse game that never ends.
Если убрать из таблицы импорта ReadProcessMemory (в качестве незаконного решения, не требующего перелопачивания структуры EXE, а только HEX-редактора, можно затереть названием какой-нибудь другой 17-буквенной функции kernel32, например, GetCurrentProcess), бинарник продолжает работать, но уже не даёт ни одного срабатывания на VirusTotal. Подозреваю, что там в каком-нибудь недостижимом пути исполнения какая-нибудь ерунда уровня ReadProcessMemory(GetCurrentProcess(), ...), т. к. если такое нужно сделать один раз, это может быть проще SEH или VirtualQuery.

Кстати, упоминавшийся в >>16218 баг был из-за того, что объекты сцены сдвигались, соответственно, и дерево апдейтилось в Newton-коллбэке http://newtondynamics.com/wiki/index.php5?title=NewtonSetTransform, который вызывается в ходе NewtonUpdate в потоках физики, а не потоке, дёрнувшем саму NewtonUpdate. Когда я делал физику, я ввиду своей наивности проигнорировал параметр с недвусмысленным названием threadIndex, а старое дерево не меняло топологию на лету (требуя явно вызывать Rebuild) и поэтому слабо портилось при гонке.

>>16349
Зелёным цветом показаны объекты, серо-синим вокруг них — узлы пространственного дерева (BVH), жёлтым — запрашиваемый объём, объекты внутри которого нужно вернуть. Обойдённые для этого узлы подсвечиваются красным. Если узел оказался полностью вне объёма, значит, все объекты внутри него можно сразу отбросить, не проверяя дальше (в этом весь смысл такой структуры). Если узел подсвечен сиреневым, то с точностью до наоборот: он полностью попал внутрь объёма и объекты внутри него можно сразу вернуть, не проверяя по отдельности. Выигрыш демонстрируется тем, что число проверок < числа объектов. Красная полоска над узлом эмпирически учитывает внесённые в него изменения, узел автоматически перестраивается, когда она переполнилась. По бенчмаркам всё плохо (но я пока не сделал нормальный бенчмарк, учитывающий разные сценарии, и не откалибровал логику автоперестроений), зато использовать проще, чем прежнюю реализацию, т. к. не нужно перестраивать руками.
No. 19685    
152431309321.png-(19.33KB, 689×824, _resetstkoflw.png)
19685
Всегда хотел это проверить =3.
No. 20299    
Жив еще, значит. Я спокоен.
No. 21263    
Неужели этот уютный проект мертв? Не могу в это поверить. Я думал, вернее надеялся, что ты, подобно разработчику Dwarf Fortress, будешь пилить вечно.
No. 21321    
Там всякую древность пробампили. А предыдущий тред по этому движку настолько стар, что он уже утонул. Утонул здесь.
Старость - это когда твой тред утонул на чиочане.
No. 21335    
155010468741.png-(368.87KB, 600×500, 71879815_p0.png)
21335
Я написал пост с планами, нытьём и одой одной транковой фиче Free Pascal, но там нужна Сырна для чуть большей убедительности. Мне очень стыдно, но подождите ещё немного, я больше не буду раскрашивать рисунки 4 года ><". Настолько не хотел этим заниматься, что N5→N1 выучил.
No. 21341    
>>21335
Не стыдись, няша, это же твой проект. Ты делаешь его так, как хочешь. Я буду ждать апдейтов. На мой взгляд, у тебя интересный, самобытный проект.
No. 21361    
>>21335
>N5→N1 выучил
Посоветуешь литературы?
No. 21444    
>>21361
...
No. 21738    
Не утонуть
No. 24723    
160097272762.png-(125.11KB, 1165×1322, Untitled-2.png)
24723
Совершенно случайно обнаружил во Free Pascal’е SSE-интринсики! «А что, так можно было?»

Похоже, фича в разработке (гуглятся анонсы и обсуждения в fpc-devel за начало этого года): соответствующий инклюд должен был бы попадать в модуль System, но на данный момент всегда закомментирован. Если проигнорировать это и без задней мысли скопипастить internproc-объявления из compiler/rtl/i386/cpummprocs.inc себе — на скриншоте переобъявлены интринсики для movups(регистр ← память), movups(память ← регистр) и maxps(регистр ← регистр, регистр), то вроде как всё работает и компилятор берёт на себя распределение и спиллинг регистров, как и должно быть. Очешуеть просто, ускорение векторных расчётов — а это обработка картиночек и моделечек — в 10 раз, ценой специальных, условно компилируемых реализаций примитивных операций, таких как operator +(vec4, vec4) или function max(vec4, vec4), притом эти варианты даже проще оригинала: max(A, B) → R реализуется, как видно, как
movups(R, maxps(movups(A), movups(B)));

против
R.x := max(A.x, B.x);

R.y := max(A.y, B.y);
R.z := max(A.z, B.z);
R.w := max(A.w, B.w);

Ща дорисую, ща-ща, сек.

>>21361
Вряд ли смогу что-то конкретное посоветовать, т. к. по сути я, прочитав Нечаеву («Ты теперь свободен от текстов про Путятина?»), пошёл ковырять с блокнотиком неадаптированный контент (книги и ВН, невыносимо сложно только первую тысячу часов[/unironically]; кстати, если есть 2 часа, глянь десантниц https://vk.cc/8sWwSL) — где Нечаеву можно заменить произвольным учебником по БАЗЕ, а уж контент сугубо дело вкуса (https://vk.com/topic-57363092_29501407?post=7). Единственное что, для начала просто необходимо взять что-то с существующим переводом, т. к. есть тысячи способов ничего не понять или понять неправильно, которые нейтрализуются только опытом.
No. 24724    
160101503531.png-(2.90KB, 469×88, max.png)
24724
>>24723
>в 10 раз
У тебя там четыре непредсказуемых перехода в одной функции - конечно оно тормозить будет. Не знаю, может ли паскаль записать флоат в инт не перекодируя битики, но если может, то попробуй высчитать маску по условию и записать в результат без условия. Будет всё ещё медленно, но не настолько.

А вообще, я бы на твоём месте давно бы написал компилятор паскаля в сишку, и там бы сишный компилятор полуавтоматически это всё делал.
No. 24733    
160106239928.png-(33.83KB, 802×356, max [mask].png)
24733
>>24724
Да, не подумал, у меня исходные данные триггерят худший случай с полностью непредсказуемыми ветками. Для сравнения проверил на полностью предсказуемых (pred) и сделал безбранчевый вариант (mask).
Относительно друг друга они работают за время, относящееся как
(vector) 1 : (scalar-pred) 2,1 : (scalar-unpred) 10 : (mask-pred) 3 : (mask-unpred) 3 (неудивительно).

Ранее я считал, что переносы между флоатовыми и целочисленными регистрами жутко дорогие: так, в Java при домножении 8-битного цвета на альфу у меня получался выигрыш в 7–13 раз (https://ideone.com/vj13We), если делать это не прямым
float alpha;

for (each pixel) pixel8 = round(pixel8 * alpha);
а, скажем,
int alpha10 = round(alpha * 1024); // 10 бит точности — эмпирическая цифра

for (each pixel) pixel8 = (pixel8 * alpha10 + 512) >> 10;
— в целых числах.

У @oldnewthing были статьи про SSE-трюки, где он прожужжал все уши domain crossing penalty:
>There are a few ways to load constants into SSE registers.
> • Load them from memory.
> • Load them from general purpose registers via movd.
> • Insert selected bits from general purpose registers via pinsr[b|w|d|q].
> • Try to calculate them in clever ways.
>Loading constants from memory incurs memory access penalties. Loading or inserting them from general purpose registers incurs cross-domain penalties. So let’s see what we can do with clever calculations.

Я даже думаю (так, примерно почувствовал), что в случае с альфой это связано не столько с domain crossing, сколько с латентностями флоатовых вычислений, которые вылезают при попытке сделать с результатом что-то интересное, вроде пересылки в целочисленный регистр. С бранчами вместо арифметики это не проявилось, но в целом касты, в т. ч. реинтерпрет_касты, между интами и флоатами без явной необходимости мне видятся такой себе идеей.

Кроме того.

Хотя для замера я расписал максимумы упрощённо, моя настоящая реализация соответствует определённой в IEEE 754 функции maxNum: если один из аргументов — NaN, она возвращает другой. Не так страшно, как звучит: если наивный максимум — это
if a > b then result := a else result := b;
то IEEE-комплиантный — его небольшая модификация:
if (a > b) or (b <> b) then result := a else result := b;
SSE этого, может быть, ради экономии транзисторов в 2000 году, не предусматривает (или же она детерминированно, если один из аргументов — NaN, возвращает не другой, а строго b), и я не уверен, можно ли полагаться на это в шейдерах, но это очень удобное свойство, и вот почему.

Мы постоянно работаем с величинами, которые можно рассматривать как веса эффектов. Тот же вклад диффузного освещения выражается косинусом угла между нормалью и направлением на источник света, иными словами, их скалярным произведением. Но в неосвещённом полупространстве косинус становится отрицательным, а вклад должен быть нулевым, поэтому окончательная формула принимает вид
diffuse = max(0.0, dot(normal, vec_to_light));
В более сложных случаях, той же модели Кука-Торренса, у нас появляется целая пачка таких промежуточных коэффициентов, отрицательность которых нам в этот раз даже и не страшна сама по себе, но они возводятся в степени, и принципиальное отличие между нулевым и отрицательным флоатами в том, что ряд функций, в первую очередь собственно pow(x, p), определены как возвращающие NaN для отрицательного x. По этой причине автор статьи https://habr.com/ru/post/424453/ (оригинал: https://learnopengl.com/PBR/Lighting) постоянно параноит отрицательность через max(0.0, value), тогда как с IEEE-комплиантным max() этого не нужно делать (по крайней мере в данном случае) — достаточно оставить финальный max(0.0, specular), который сделает из пропагейтнувшегося NaN’а тот же 0. В другой раз у нас может быть перемножение отрицательных чисел, которое вернёт не NaN, а неверный положительный результат, но в целом ряде случаев этого нет и можно спокойно убрать кучу паранойи.

Так вот, скалярный IEEE-комплиантный вариант, дописанный в ряд выше, показывает себя следующим образом:
(scalar-precise-pred) 2,2 : (scalar-precise-unpred) 11
то есть почти идентично наивным 2,1 : 10.

Таким же приёмом (добавлением b <> b) этого можно добиться и на SSE (https://stackoverflow.com/a/32332219). На FPC-интринсиках это выглядит как
function max(const a, b: Vec4f32): Vec4f32;

var
    ma, mb: __m128;
begin
    ma := _movups(@a);
    mb := _movups(@b);
    _movups(@result, _blendvps(_maxps(ma, mb), ma, _cmpps(mb, mb, {UNORD} 3)));
end;
и даёт практически идентичную чистому maxps, взятому за 1, скорость
(vector-precise) 1,05.

Аналогично — uint32((a.x > b.x) or (b.x <> b.x)) и т. д. — можно добавить поддержку NaN и маскам, но они начинают совсем явно проигрывать UPD: а нет, гениальный компилятор вычисляет это выражение через джампы, так что я переделал на форсированно побитовое uint32(a.x > b.x) or uint32(b.x <> b.x) и получился как бы не такой уж плохой результат:
(mask-precise) 6,
но меня всё ещё настораживает двукратная разница относительно этого же способа без NaN.
No. 24736    
160106293027.png-(198.33KB, 3190×3366, 70468793_p0.png)
24736
>>24734
UPD2: возможно, компилятор даже прав, вычисляя (a.x > b.x) or (b.x <> b.x) через джампы. Форсированно безджамповый вариант не взаимодействует с предсказателем и выдаёт 6 в любую погоду, а джампы выдают
(mask-precise-pred) 3,5 : (mask-precise-unpred) 11.
В предположении, что предсказатель работает (иначе зачем он нужен), реальные результаты будут гораздо ближе к 3,5, чем к 11, то есть лучше 6, и, надо заметить, однозначно (и ожидаемо) хуже исходных (scalar-precise). В частности, если мы вычисляем значение чего-то пикселеподобного и у нас вылезает конкретный результат a≷b или NaN, то у соседей, которых мы вскоре будем считать, с высокой вероятностью вылезет то же самое, поэтому предсказатель сработает лучше, чем его отсутствие.
No. 24739    
160148860641.png-(71.07KB, 1280×800, Clipboard01.png)
24739
Почему исчезла собранная версия?Несколько лет назад была, с радостью играл.А что делать вот с этим безобразием, ума не приложу.
No. 24768    
https://web.archive.org/web/20151021190423/http://410chan.org/dev/res/4274.html

просто чтобы проще было не терять
Удалить сообщение []
Пароль  
[Mod]