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

Сообщение Re[13]: Эльбрус мёртв, да здравствует Эльбрус-Б! от 22.05.2025 12:04

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

Re[13]: Эльбрус мёртв, да здравствует Эльбрус-Б!
Здравствуйте, Sinclair, Вы писали:

S>Асинхронщина в дотнете, как и везде, в первую очередь зависит от общей архитектуры и применяемых решений. Ну, вот как LMAX Disruptor взял — и написал систему трейдинга на порядок быстрее, чем это считалось теоретически возможным на Java.


Не систему трейдинга, а межпоточную lock-free круговую очередь, гвоздь программы был в ней, не везёт тебе...

В любом случае, наша реализация межпоточной очереди заметно эффективней, да еще без ограничений на её размер, в отличие от наивной реализации Disruptor.


S>И для этого не пришлось ни ломать JIT, ни переписывать компилятор, ни раскладывать данные по линейкам кеша.


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

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

Плюс у нас есть возможность ожидать на примитиве синхронизации уровня ОС, т.е. отправлять поток в спячку, освобождая аппаратный поток для других задач в отсутствии данных, а у тех безальтернативно спин-ожидание.

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

Ты код-то поизучай внимательно, он у них открыт. ))


S>Понятно, что можно криво написать софт. Непонятно, что тут может бать Бабаяновское железо.


Убрать саму необходимость оперирования "зелеными потоками", вестимо.
И не важно, в stackless реализации, как в дотнетных корутинах с их сворачиванием линейной логики в автомат или в stackful корутинах, как принято в плюсах.

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

Ведь все эти отжирающие тики проца навороты борются с недостатками современных процов и операционок поверх них, не умеющих эффективно порождать/уничтожать/переключать "родные" потоки уровня ОС.


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

S>Пример LMAX Disruptor показывает, что не всегда.

Да ты на код-то их посмотри внимательно. ))


S>Ну, так что сдерживает-то? Сказки про комитеты, которые запрещают вам ковыряться в носу, рассказывать не надо. Простой вариант: берём дотнет, изобретаем набор атрибутов для лэйаута, делаем свой компайл-тайм-генератор типов


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

Я о С/С++, где ситуация сложилась примерно как в HTML-стандартах, где лидерам надавали по голове однажды и отстранили от работы над стандартами примерно на 20 лет, пока у красноглазиков опенсорсные их компиляторы и браузеры не дорастут до среднего по индустрии качества. ))

Потеряли примерно 20 лет что в деле развития стандартов веба, что в деле развития языков для эффективного кода.


S>с выровненными по кэшу данными. Работы на один вечер.


Атрибуты для лейаута полей в дотнете есть, вручную данные разносятся легко.
А чтобы не вручную — это надо вмешиваться в выравнивание еще на уровне выделения памяти, бо сейчас эти зазоры берутся из расчёта выравнивания адресов объектов по ширине слова, т.е. произвольного выравнивани с т.з. ширины линейки кеша, получаем перерасход памяти на ровном месте. В плюсах хотя бы можно вмешаться в физическое выравнивание объектов в памяти, самим этой памятью управляя.


S>Если не знаем, на чём будет исполняться код — переносим генератор в рантайм. Работы на два вечера.

S>Или берём clang, llvm, и делаем то же самое прямо в кодогенераторе. Работы на пару недель.

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

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

На деле, подобные вопросы обсуждаются уже даже больше, чем 20 лет, но из-за красноглазиков буксовали, бо их gcc безбожно отставал от кучи других компиляторов, которые были востребованы именно тем, что были лучше gcc. А коль стандарты языка заморозили и дали gcc возможность их догнать, то (a) куча альтернативных компиляторов просто вымерла за ненадобностью в этой кривой реальности и (b) вопросы стандартизации ABI (т.е. возможности манипулирования инфой об объектах в рантайм) были заморожены на 25+ лет.

Я просто думал, что коллеги в курсе происходившего вокруг основных ЯП, с которых "взлетает" любое железо. ))


V>>Имелись ввиду задачи активного обмена данными м/у потоками.

S>Для начала нужно понять, зачем вообще потребовался активный обмен данными между потоками. Может, там надо по-другому работу распределить?

Ну ты же привёл пример Disruptor — а основой их решения как раз являются эффективные межпоточные очереди.
Как и у нас, конечно, только за счёт них, родимых, и выезжаем. ))

Ну а понимание "зачем" — это к тебе должен быть вопрос по теме организации эффективных вычислений на современных архитектурах.
Т.е. это как признаваться, что не сделал уроки.


V>>Блин, "более удачные структуры данных"... ))

S>А то.

Да садись, два, хосподя...

Как ты вообще собрался утилизировать мощность в ядрах, исключив обмен данными между ядрами/потоками?
На независимых по данным задачах?
А если требуется именно решение одной некоей задачи организовать максимально эффективно?

И что, можно всерьёз об этом рассуждать с умным лицом, что ле? ))
ТА блин, на самых первых серьезных векторных/параллельных компах столкнулись со всеми этими проблемами, которые не решены толком до сих пор:
https://en.wikipedia.org/wiki/CDC_STAR-100

The problem was compounded by the fact that the STAR had a slower cycle time than the 7600 (40 ns vs 27.5 ns). So the vector length needed for the STAR to run faster than the 7600 occurred at about 50 elements; if the loops were working on data sets with fewer elements, the time cost of setting up the vector pipeline was higher than the time savings provided by the vector instruction(s).

When the machine was released in 1974, it quickly became apparent that the general performance was disappointing. Very few programs can be effectively vectorized into a series of single instructions; nearly all calculations will rely on the results of some earlier instruction, yet the results had to clear the pipelines before they could be fed back in. This forced most programs to pay the high setup cost of the vector units, and generally the ones that did "work" were extreme examples.

Таким образом, длина вектора, необходимая для того, чтобы STAR работал быстрее, чем 7600, составляла около 50 элементов; если циклы работали с наборами данных с меньшим количеством элементов, временные затраты на настройку векторного конвейера были выше, чем экономия времени, обеспечиваемая векторной(ыми) инструкцией(ями).

Когда машина была выпущена в 1974 году, быстро стало очевидно, что общая производительность была разочаровывающей. Очень немногие программы могут быть эффективно векторизованы в ряд отдельных инструкций; почти все вычисления будут полагаться на результаты некоторых более ранних инструкций, однако результаты должны были очистить конвейеры, прежде чем их можно было подать обратно. Это вынуждало большинство программ платить высокую стоимость настройки векторных блоков, и, как правило, те, которые «работали», были крайними примерами.



V>>E2k в макетах сначала показали в 90-е (это все последующие микропроцессорные Эльбрусы которые).

S>Речь в топике про Эльбрус-Б. Эль-22, напомню, к E2K никакого отношения не имеет.

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

А сейчас, на современных доступных ср-вах разработки, эмулирования и макетирования на современных ПЛИСАХ — да это вообще как два пальца об асфальт со всеми этими макетами.

Вопрос, действительно, в способе видения проблемы и в наборе идей, составляющих решение этой проблемы.
Т.е., откуда берётся сама проблематика — мне хорошо понятно и лично мне интересно, конечно...

Тем более, что подобные языки уже были когда-то в 70-80-е, кое-какие развивались тихой сапой и до сегодня, я как-то давал список таких языков.
В студенчестве мы "на бумажке" программировали на одном из таких языков по теме параллельных вычислений (предмет "устройство современных выч. комплексов и операционных систем", могу ошибиться с точным названием, но суть именно такая).
Re[13]: Эльбрус мёртв, да здравствует Эльбрус-Б!
Здравствуйте, Sinclair, Вы писали:

S>Асинхронщина в дотнете, как и везде, в первую очередь зависит от общей архитектуры и применяемых решений. Ну, вот как LMAX Disruptor взял — и написал систему трейдинга на порядок быстрее, чем это считалось теоретически возможным на Java.


Не систему трейдинга, а межпоточную lock-free круговую очередь, гвоздь программы был в ней, не везёт тебе...

В любом случае, наша реализация межпоточной очереди заметно эффективней, да еще без ограничений на её размер, в отличие от наивной реализации Disruptor.


S>И для этого не пришлось ни ломать JIT, ни переписывать компилятор, ни раскладывать данные по линейкам кеша.


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

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

Плюс у нас есть возможность ожидать на примитиве синхронизации уровня ОС, т.е. отправлять поток в спячку, освобождая аппаратный поток для других задач в отсутствии данных, а у тех безальтернативно спин-ожидание.

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

Ты код-то поизучай внимательно, он у них открыт. ))


S>Понятно, что можно криво написать софт. Непонятно, что тут может бать Бабаяновское железо.


Убрать саму необходимость оперирования "зелеными потоками", вестимо.
И не важно, в stackless реализации, как в дотнетных корутинах с их сворачиванием линейной логики в автомат или в stackful корутинах, как принято в плюсах.

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

Ведь все эти отжирающие тики проца навороты борются с недостатками современных процов и операционок поверх них, не умеющих эффективно порождать/уничтожать/переключать "родные" потоки уровня ОС.


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

S>Пример LMAX Disruptor показывает, что не всегда.

Да ты на код-то их посмотри внимательно. ))


S>Ну, так что сдерживает-то? Сказки про комитеты, которые запрещают вам ковыряться в носу, рассказывать не надо. Простой вариант: берём дотнет, изобретаем набор атрибутов для лэйаута, делаем свой компайл-тайм-генератор типов


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

Я о С/С++, где ситуация сложилась примерно как в HTML-стандартах, где лидерам надавали по голове однажды и отстранили от работы над стандартами примерно на 20 лет, пока у красноглазиков опенсорсные их компиляторы и браузеры не дорастут до среднего по индустрии качества. ))

Потеряли примерно 20 лет что в деле развития стандартов веба, что в деле развития языков для эффективного кода.


S>с выровненными по кэшу данными. Работы на один вечер.


Атрибуты для лейаута полей в дотнете есть, вручную данные разносятся легко.
А чтобы не вручную — это надо вмешиваться в выравнивание еще на уровне выделения памяти, бо сейчас эти зазоры берутся из расчёта выравнивания адресов объектов по ширине слова, т.е. произвольного выравнивания с т.з. ширины линейки кеша, получаем перерасход памяти на ровном месте. В плюсах хотя бы можно вмешаться в физическое выравнивание объектов в памяти, самим этой памятью управляя.


S>Если не знаем, на чём будет исполняться код — переносим генератор в рантайм. Работы на два вечера.

S>Или берём clang, llvm, и делаем то же самое прямо в кодогенераторе. Работы на пару недель.

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

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

На деле, подобные вопросы обсуждаются уже даже больше, чем 20 лет, но из-за красноглазиков буксовали, бо их gcc безбожно отставал от кучи других компиляторов, которые были востребованы именно тем, что были лучше gcc. А коль стандарты языка заморозили и дали gcc возможность их догнать, то (a) куча альтернативных компиляторов просто вымерла за ненадобностью в этой кривой реальности и (b) вопросы стандартизации ABI (т.е. возможности манипулирования инфой об объектах в рантайм) были заморожены на 25+ лет.

Я просто думал, что коллеги в курсе происходившего вокруг основных ЯП, с которых "взлетает" любое железо. ))


V>>Имелись ввиду задачи активного обмена данными м/у потоками.

S>Для начала нужно понять, зачем вообще потребовался активный обмен данными между потоками. Может, там надо по-другому работу распределить?

Ну ты же привёл пример Disruptor — а основой их решения как раз являются эффективные межпоточные очереди.
Как и у нас, конечно, только за счёт них, родимых, и выезжаем. ))

Ну а понимание "зачем" — это к тебе должен быть вопрос по теме организации эффективных вычислений на современных архитектурах.
Т.е. это как признаваться, что не сделал уроки.


V>>Блин, "более удачные структуры данных"... ))

S>А то.

Да садись, два, хосподя...

Как ты вообще собрался утилизировать мощность в ядрах, исключив обмен данными между ядрами/потоками?
На независимых по данным задачах?
А если требуется именно решение одной некоей задачи организовать максимально эффективно?

И что, можно всерьёз об этом рассуждать с умным лицом, что ле? ))
Та блин, на самых первых серьезных векторных/параллельных компах столкнулись со всеми этими проблемами, которые не решены толком до сих пор:
https://en.wikipedia.org/wiki/CDC_STAR-100

The problem was compounded by the fact that the STAR had a slower cycle time than the 7600 (40 ns vs 27.5 ns). So the vector length needed for the STAR to run faster than the 7600 occurred at about 50 elements; if the loops were working on data sets with fewer elements, the time cost of setting up the vector pipeline was higher than the time savings provided by the vector instruction(s).

When the machine was released in 1974, it quickly became apparent that the general performance was disappointing. Very few programs can be effectively vectorized into a series of single instructions; nearly all calculations will rely on the results of some earlier instruction, yet the results had to clear the pipelines before they could be fed back in. This forced most programs to pay the high setup cost of the vector units, and generally the ones that did "work" were extreme examples.

Таким образом, длина вектора, необходимая для того, чтобы STAR работал быстрее, чем 7600, составляла около 50 элементов; если циклы работали с наборами данных с меньшим количеством элементов, временные затраты на настройку векторного конвейера были выше, чем экономия времени, обеспечиваемая векторной(ыми) инструкцией(ями).

Когда машина была выпущена в 1974 году, быстро стало очевидно, что общая производительность была разочаровывающей. Очень немногие программы могут быть эффективно векторизованы в ряд отдельных инструкций; почти все вычисления будут полагаться на результаты некоторых более ранних инструкций, однако результаты должны были очистить конвейеры, прежде чем их можно было подать обратно. Это вынуждало большинство программ платить высокую стоимость настройки векторных блоков, и, как правило, те, которые «работали», были крайними примерами.



V>>E2k в макетах сначала показали в 90-е (это все последующие микропроцессорные Эльбрусы которые).

S>Речь в топике про Эльбрус-Б. Эль-22, напомню, к E2K никакого отношения не имеет.

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

А сейчас, на современных доступных ср-вах разработки, эмулирования и макетирования на современных ПЛИСАХ — да это вообще как два пальца об асфальт со всеми этими макетами.

Вопрос, действительно, в способе видения проблемы и в наборе идей, составляющих решение этой проблемы.
Т.е., откуда берётся сама проблематика — мне хорошо понятно и лично мне интересно, конечно...

Тем более, что подобные языки уже были когда-то в 70-80-е, кое-какие развивались тихой сапой и до сегодня, я как-то давал список таких языков.
В студенчестве мы "на бумажке" программировали на одном из таких языков по теме параллельных вычислений (предмет "устройство современных выч. комплексов и операционных систем", могу ошибиться с точным названием, но суть именно такая).