Информация об изменениях

Сообщение Re[14]: вопрос hi_octane про c# от 06.09.2020 11:56

Изменено 06.09.2020 12:26 vdimas

Re[14]: вопрос hi_octane про c#
Здравствуйте, Sinclair, Вы писали:

S>>>Вы устанете искать сценарий, в котором статическое порождение кода выиграет что-то заметное у динамики.

V>>Это работает ровно до тех пор, пока работает аргумент "все-равно база тормозит".
S>Нет, почему. Вот, для того же linq2d — сравниваем динамику с кэшированием против статики (ручного выписывания аналогичного кода), выигрыша не видим. Никаких сотен миллисекунд — даже один процент наиграть не удаётся.

Поиграй с распространением констант в С++.

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

Фишка в том, что и обычная и векторная арифметика используют одни и те же аппаратные блоки ядер, т.е. унутре проца всё происходит с одинаковой скоростью, т.е. выигрыш сугубо "архитектурный" получается, а не волшебный-аппаратный. Поэтому, если векторные регистры используются не для векторных операций (а там есть и не векторные, ими можно как обычным файлом регистров распоряжаться), то быстродействие получается такое же. А чуть лучше оно получается в не-векторных операциях от того, что векторные регистры рассматриваются как дополнительный файл регистров, т.е. трафик общения проца и кеша 0-го уровня может быть заметно ужат.

И да, что с чем ты собрался сравнивать?
Один запрос linq компиллируется от единиц до десятков ms.
Это не в синтетическом тесте, где один и тот же запрос компиллируется в цикле — а замеры на реальных приложениях.
Грубо, одну форму открыть — сотни ms только на компиляцию нескольких linq-запросов (обычно 3-5 на форму).
Приложение долго стартует (с заметной задержкой), долго открывает экраны (особенно, когда некий экран открывается в первый раз).

И твой кодогенератор, когда впервые отрабатывает — тоже сам по себе тормозит, на JIT и всё прочее.
т.е. еще до того, как начнёт работать.
И даже когда начнёт — первый раз сильно тормозит.

Для примера, замена просто кода, типа:
SomeScheme s1 = new ...;
s1.Add(a, b, "c");
s1.Add(e, f, "g");
...
s2.Add...

На вручную сериализованные данные ускорило старт приложения с ~800 ms до ~200 ms, т.е. 600 ms отъедалось лишь на инициализацию, т.е. первый (и последний) прогон некоего кода, примерно эквивалентного показанному.

Далее.
Всякие многократно упомянутые тобой "стратегии подстановки несуществующих точек" (жёстко задаваемые в коде, обычно) и прочее — ты, действительно, не в курсе, что на плюсах чуть ли не половина (если не большая часть) всего современного кода (сидящего поверх STL и Boost) — это стратегии стратегиями подгоняют?
"По глазам вижу" (С), что знал.
(помню прошлые обсуждения с тобой, кое-какое представление о плюсовых шаблонах ты имеешь)


S>Автоматическая векторизация при этом позволяет отказаться от статического порождения кода под все варианты целевых платформ.


Это если под x86.
Ты ведь курсе, например, что в природе нет активных поддерживаемых x86-х сборок Линукс?
Они все давно переползли на x86_x64, а там изкоробки 32 и 64-битные векторные операции, т.е. куча поколений, которые были для x86 — они пропущены для случая x86_x64.

Более поздние расширения могут пригодиться лишь в тех уникальных случаях, где надо оперировать векторами из памяти, длиной более 4-х (8 и 16), но это не твой случай, когда речь о представлении цвета.


S>>>А вот сценариев проигрыша — масса.

V>>Разве что для случая херак-херак и в продашен.
S>Ну, так нам этот случай и интересен.

Для заказухи если — может быть.
Ты попробуй коробочный подобный продукт продай — в том же магазине приложений смартфонов или "просто на рынке приложений". ))
Оглянись по сторонам, плиз, какого уровня идёт современное ПО.
Такое ощущение (из твоей подачи), что ты продолжаешь жить реалиями середины 2000-х.
За что тогда охотно платили бабки, сегодня это всё доступно абсолютно даром и даже в куче независимых реализаций.
В общем, ты попробуй заставь юзера выложить денюжку за "херак-херак".


S>Потому что время хочется тратить не на борьбу с ручным вылизыванием обхода массива, а на выбор алгоритмов.


Я тебе показывал хелперы даже для unsafe C#, просто чтобы показать идею.
На плюсах там в разы больше навертеть можно.

Если есть задача — под неё всё-равно хелперы писать надо.
Например, для оперирования цветами с альфа-каналами — свои хелперы.
Причём, от эффективности этих хелперов производительность зависит не меньше, чем от эффективности обхода массива.

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


S>Вон, как в Савола — на numpy предлагается реализация с двойным проходом для пре-аггрегирования.

S>Бенчмарк показывает, что эффективнее проходить один раз. Высокоуровневый код позволяет проверить эти гипотезы за минуты.

Тебе показывали реализацию на Питоне, которая не сложнее твоей на linq2d, зачем ты продолжаешь использовать тот аргумент, который уже бит?
Нарисуй себе подобные хелперы для плюсов и будет тебе примерно такое же счастье...

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

Любые эксперименты начинаются с воссоздания окружения "под задачу".
Вот даже ты этим занялся, хотя на C# это совсем не жёсткое правило, бо там многое есть изкаробки, но ты же занялся? ))
А по итогу сравниваешь некий фреймворк, отожравший дохрена времени, с голым Си...
Ну вот поэтому опять неинтересно.

И особенно неинтересна примерно такая наивность: "я тут потратил прилично времени я СДЕЛАЛ!!! а теперь сделайте ВЫ, или позорно убегайте!!!"
Честный исследователь бы сам (бо не маленький) исследовал бы основные мейнстримовые инструменты мейнстримовых платформ и выдал бы уже готовое честное сравнение.
(как это делаю я, когда что-то с чем-то сравниваю)

Ну кто тебе будет тратиться на полноценное сравнение, тем более, что там сначала надо накрутить хелперы для обработки многокомпонентного цвета?
Надо протрассировать твоё решение на предмет корректности и т.д. до бесконечности.

А, главное — зачем?
Найденные в твоём решении косяки не произведут на тебя впечатления, точно так же как проигрыш в производительности тоже не произведёт впечатления.

Это знаешь, как с Роем Джонсоном когда-то супертяжи отказывались драться: потому что проиграть поднявшемуся на 3 весовые категории средневесу проигрывать стыдно.
А выигрывать тоже нифига не почётно.
Вот примерно так и у тебя — косяки будут объяснены "кругом решаемых задач" или даже "постановкой задачи", а проигрыш в производительности (в зависимости от его размера) может быть мгновенно перевёрнут в "победу", через рассуждения примерно такого плана: "вот видите, мы практически достигли производительности нейтива, хотя продолжаем оставаться в рамках высокоуровневого инструмента" и далее миллион вот этих бесконечнейших спекуляций на тему, "почему высокоуровневое лучше". Осталось выяснить, почему высокоуровневым может быть решение только на C#, а другим низзя? ))
Re[14]: вопрос hi_octane про c#
Здравствуйте, Sinclair, Вы писали:

S>>>Вы устанете искать сценарий, в котором статическое порождение кода выиграет что-то заметное у динамики.

V>>Это работает ровно до тех пор, пока работает аргумент "все-равно база тормозит".
S>Нет, почему. Вот, для того же linq2d — сравниваем динамику с кэшированием против статики (ручного выписывания аналогичного кода), выигрыша не видим. Никаких сотен миллисекунд — даже один процент наиграть не удаётся.

Поиграй с распространением констант в С++.

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

Фишка в том, что и обычная и векторная арифметика используют одни и те же аппаратные блоки ядер, т.е. унутре проца всё происходит с одинаковой скоростью, т.е. выигрыш сугубо "архитектурный" получается, а не волшебный-аппаратный. Поэтому, если векторные регистры используются не для векторных операций (а там есть и не векторные, ими можно как обычным файлом регистров распоряжаться), то быстродействие получается такое же. А чуть лучше оно получается в не-векторных операциях от того, что векторные регистры рассматриваются как дополнительный файл регистров, т.е. трафик общения проца и кеша 0-го уровня может быть заметно ужат.

И да, что с чем ты собрался сравнивать?
Один запрос linq компиллируется от единиц до десятков ms.
Это не в синтетическом тесте, где один и тот же запрос компиллируется в цикле — а замеры на реальных приложениях.
Грубо, одну форму открыть — сотни ms только на компиляцию нескольких linq-запросов (обычно 3-5 на форму).
Приложение долго стартует (с заметной задержкой), долго открывает экраны (особенно, когда некий экран открывается в первый раз).

И твой кодогенератор, когда впервые отрабатывает — тоже сам по себе тормозит, на JIT и всё прочее.
т.е. еще до того, как начнёт работать.
И даже когда начнёт — первый раз сильно тормозит.

Для примера, замена просто кода, типа:
SomeScheme s1 = new ...;
s1.Add(a, b, "c");
s1.Add(e, f, "g");
...
s2.Add...

На вручную сериализованные данные ускорило старт приложения с ~800 ms до ~200 ms, т.е. 600 ms отъедалось лишь на инициализацию, т.е. первый (и последний) прогон некоего кода, примерно эквивалентного показанному.

Далее.
Всякие многократно упомянутые тобой "стратегии подстановки несуществующих точек" (жёстко задаваемые в коде, обычно) и прочее — ты, действительно, не в курсе, что на плюсах чуть ли не половина (если не большая часть) всего современного кода (сидящего поверх STL и Boost) — это стратегии стратегиями подгоняют?
"По глазам вижу" (С), что знал.
(помню прошлые обсуждения с тобой, кое-какое представление о плюсовых шаблонах ты имеешь)


S>Автоматическая векторизация при этом позволяет отказаться от статического порождения кода под все варианты целевых платформ.


Это если под x86.
Ты ведь курсе, например, что в природе нет активных поддерживаемых x86-х сборок Линукс?
Они все давно переползли на x86_x64, а там изкоробки 32 и 64-битные векторные операции, т.е. куча поколений, которые были для x86 — они пропущены для случая x86_x64.

Более поздние расширения могут пригодиться лишь в тех уникальных случаях, где надо оперировать векторами из памяти, длиной более 4-х (8 и 16), но это не твой случай, когда речь о представлении цвета.


S>>>А вот сценариев проигрыша — масса.

V>>Разве что для случая херак-херак и в продашен.
S>Ну, так нам этот случай и интересен.

Для заказухи если — может быть.
Ты попробуй коробочный подобный продукт продай — в том же магазине приложений смартфонов или "просто на рынке приложений". ))
Оглянись по сторонам, плиз, какого уровня идёт современное ПО.
Такое ощущение (из твоей подачи), что ты продолжаешь жить реалиями середины 2000-х.
За что тогда охотно платили бабки, сегодня это всё доступно абсолютно даром и даже в куче независимых реализаций.
В общем, ты попробуй заставь юзера выложить денюжку за "херак-херак".


S>Потому что время хочется тратить не на борьбу с ручным вылизыванием обхода массива, а на выбор алгоритмов.


Я тебе показывал хелперы даже для unsafe C#, просто чтобы показать идею.
На плюсах там в разы больше навертеть можно.

Если есть задача — под неё всё-равно хелперы писать надо.
Например, для оперирования цветами с альфа-каналами — свои хелперы.
Причём, от эффективности этих хелперов производительность зависит не меньше, чем от эффективности обхода массива.

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


S>Вон, как в Савола — на numpy предлагается реализация с двойным проходом для пре-аггрегирования.

S>Бенчмарк показывает, что эффективнее проходить один раз. Высокоуровневый код позволяет проверить эти гипотезы за минуты.

Тебе показывали реализацию на Питоне, которая не сложнее твоей на linq2d, зачем ты продолжаешь использовать тот аргумент, который уже бит?
Нарисуй себе подобные хелперы для плюсов и будет тебе примерно такое же счастье...

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

Любые эксперименты начинаются с воссоздания окружения "под задачу".
Вот даже ты этим занялся, хотя на C# это совсем не жёсткое правило, бо там многое есть изкаробки, но ты же занялся? ))
А по итогу сравниваешь некий фреймворк, отожравший дохрена времени, с голым Си...
Ну вот поэтому опять неинтересно.

И особенно неинтересна примерно такая наивность: "я тут потратил прилично времени я СДЕЛАЛ!!! а теперь сделайте ВЫ, или позорно убегайте!!!"
Честный исследователь бы сам (бо не маленький) исследовал бы основные мейнстримовые инструменты мейнстримовых платформ и выдал бы уже готовое честное сравнение.
(как это делаю я, когда что-то с чем-то сравниваю)

Ну кто тебе будет тратиться на полноценное сравнение, тем более, что там сначала надо накрутить хелперы для обработки многокомпонентного цвета?
Надо протрассировать твоё решение на предмет корректности и т.д. до бесконечности.

А, главное — зачем?
Найденные в твоём решении косяки не произведут на тебя впечатления, точно так же как проигрыш в производительности тоже не произведёт впечатления.

Это знаешь, как с Роем Джонсоном когда-то супертяжи отказывались драться: потому что проиграть поднявшемуся на 3 весовые категории средневесу стыдно.
А выигрывать тоже нифига не почётно.
Вот примерно так и у тебя — косяки будут объяснены "кругом решаемых задач" или даже "постановкой задачи", а проигрыш в производительности (в зависимости от его размера) может быть мгновенно перевёрнут в "победу", через рассуждения примерно такого плана: "вот видите, мы практически достигли производительности нейтива, хотя продолжаем оставаться в рамках высокоуровневого инструмента" и далее миллион вот этих бесконечнейших спекуляций на тему, "почему высокоуровневое лучше". Осталось выяснить, почему высокоуровневым может быть решение только на C#, а другим низзя? ))