Re[63]: MS забило на дотнет. Питону - да, сишарпу - нет?
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.09.21 05:15
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Но, наоборот, это указатель на VMT обитает в виде поля typeinfo, т.е. требуется два разыменования только чтобы достать адрес VMT.

Конечно. Там же ещё может быть и доступ через интерфейс — тогда надо сначала пойти в таблицу интерфейсов, чтобы узнать адрес нужной VMT.

V>Простого двоичного.

Смотря как организовано это простое двоичное дерево. Если в нём известны точные типы, то да.
А если там опять виртуальный вызов — то всё грустно.
V>Количество операций сравнения у тебя идентично в узлах-ветках, насколько я понимаю.
V>(особенно в оригинальной твоей версии с вручную заинлайненым двоичным поиском, в версии с линейным поиском чуть больше, но там может быть выигрыш за счёт специфики происходящего в проце)
В версии с двоичным поиском мы выигрываем за счёт гарантий локальности кэша. То есть весь поиск с четырьмя ветвлениями происходит без какого-либо обмена с памятью; для случайно организованного двоичного дерева это не так.

V>Это еще один пункт к той моей идее, что арность узлов может расти (например, геометрически) при росте дерева вглубину, т.е. при большом кол-ве данных арность узлов-листьев будет расти.

V>Это даст что-то O(log(log(N))
Нет, это не даст O(log(log(N)).

V>Например, арность корня может быть небольшой в той моей идее.

V>Допустим даже 2.
V>И всегда представлять из себя узел-ветку.
Это как раз будет убивать производительность на маленьких коллекциях.

S>>Дотнет прекрасно работает с генерик типами в пару десятков уровней вложенности.


V>Это когда однократно скомпилял и всё.

V>У тебя же динамически эти типы производятся по мере роста дерева.
Это тоже происходит однократно. То есть как только мы хотя бы раз в приложении достигли глубины дерева 4, у нас есть готовый для этого код. Все последующие деревья глубиной до 4х обходятся без компиляции.

V>Вот тот "моноблочный" будет разный для разных глубин, если тебе удастся всё заинлайнить.

Совершенно верно. Это именно то, чего я хочу добиться.

V>Только не "мы", а джит будет иметь дело с разными типами при изменении данных в дереве.

А то.

V>Это понятно, потому что тип известен.

Да. И это не помогает — см. график.

V>>>Хранить индекс в узле-ветке можно так, грубо:

V>>>
V>>>struct Cell {
V>>>   int _index;
V>>>   NodeBase _child;
V>>>   delegate * <NodeBase, ref T> _getItem;
V>>>}
V>>>

S>>Вот не запуская бенчмарки вижу — не взлетит.

V>Почему?

Потому что не взлетает даже когда у нас "рекурсивный" вызов делается напрямую, по call CONST. А вы предлагаете добавить косвенный вызов — который не будет предсказываться процессором.
Плюс к этомк добавляем мелочи типа разрушения локальности индексов. Cell занимает 20 байт на x64, и наши index разбросаны в 320 байтах (если branchfactor == 16).

V>Красно-черный алгоритм.

Он же только для бинарных деревьев, разве нет?

V>Но твои "игры" с арностью помогли, согласно графикам.

Нет. Хорошие графики получены на гомогенных деревьях. Там код this[] не выполнял вообще никаких вызовов:
https://github.com/evilguest/atropos/blob/c5d59b008e6da8dc202e816f5c9d3863c78e8b44/Atropos/ListNode.cs#L118-L126

V>Что-то я на скорую руку не увидел графики, а можно повторить ссылку?

https://github.com/evilguest/atropos/blob/main/Atropos.Benchmarks/README.md

V>Делаем дерево дешевым в изменениях для относительно небольшого кол-ва узлов.

V>При росте арности в геометрической прогрессии 2, уже на 4-м уровне арность сравняется с твоей, на следующем уровне общее кол-во узлов уже будет равным, а далее с каждым слоем в геометрической прогрессии будет уменьшаться от твоей реализации.
Как по мне, так это сочетание недостатков обоих подходов: на "дне" у нас "длинные" листья, у которых дороги любые модификации. Плюс у нас растёт длина пути к корню, т.к. арность веток уменьшена.
Но я могу неверно считать в уме — можно либо сесть и внимательно расписать O-оценки, либо закодировать и бенчмаркнуть.

V>Отож.

V>И тогда переход вглубь к ветке или листу можно сделать через проверку типа, которая в дотнете дешевая.
Вот надо попробовать.

V>Может, потому что в дотнетной вызывается тот же метод, а у тебя на каждом уровне разный, даже если их тела в железе совпадают (с точностью до адреса псевдорекурсивного вызова).

Возможно, там срабатывает tailcall.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.