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

Сообщение Re[13]: Лялих муст дие от 14.12.2022 18:16

Изменено 14.12.2022 18:19 vdimas

Re[13]: Лялих муст дие
Здравствуйте, Pauel, Вы писали:

V>>Разница есть, дотнет в виндах использует IOCP в асинхронщине в родном режиме проактора, а в линухах epoll в его режиме реактора.

V>>Первая технология заруливает вторую.
P>На замерах этого не видно — вот я тебе и пишу — линукс стабильно быстрее винды.

На замерах ноды?
Продолжаешь троллить...


V>>И какая в опу "очередь", кстате?

V>>Это у твоей ноды однопоточная очередь, в дотнете пул потоков.
P>А ты "специалист". "однопоточная очередь" В ноде тоже пул потоков, только оркестрируется из js-ного.

В ноде пул потоков IO, но события перенаправляются в одну JS-очередь.
Мы это уже разбирали не раз, заканчивай наводить тень на плетень. ))


P>Если у нас идет 100 коннектов, а ядер всего 8, то запросы будут большей частью висеть в очереди, ибо все ядра заняты, что в дотнете, что в ноде.


Да не будут в Windows висеть, в этом и прелесть.
Все эти запросы в проакторе могут обрабатывать одновременно, хоть тысячу их, независимо от кол-ва потоков и ядер.

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

Этот режим используется нодой в линухах и виндах.

Как работает проактор:
— в систему подаётся для чтения один или несколько буферов для приёма данных, ждём принятия этих данных;
— унутре ядра ОС происходят аппаратные прерывания от картеек по мере поступления физических пакетов из сети, данные из этих пакетов раскидываются по буферам; то бишь, многие тысячи коннектов могут принимать данные "одновременно" прямо на уровне ядра, без промежуточного буферирования в буфере сокета;
— прикладной колбэк вызывается уже по готовности данных, то бишь, из прикладного колбэка не требуется опять вызывать ф-ии ядра по чтению данных.

Таким образом, вместо использования буфера сокета, используется прикладные буфера, куда сразу пишутся данные.

Буфер сокета тоже может быть, куда будут складывать те данные, которое приложение не успевает выгребать, но при правильной организации, прикладные буфера ничем не отличаются от внутренних, поэтому смысла в них немного. В чём заключается "правильное использование буферов"? — в перекрывающемся (overlapped) IO. Пользовательский код может инициировать несколько операций IO с разными буферами, идеально будет 2-3 операции. Таким образом, пока текущие принятые данные обрабатываются приложением, ядро продолжает напихивать данными поданные буфера следующей инициированной операции. И вот так по кругу эти 2-3 операции крутятся, подставляя буфера для ядерного IO.

Именно через этот способ получается насытить данные 10-гигабитных картеек в Windows через одно соединение.
В Linux не получается никаким способом, они там в экспериментах насыщали десятком независимых соединений.


V>>Давай разумного размера спецификацию JSON и тестовые данные, я тебе на коленке сделаю решение на .net core в единицы строк через кодогенерацию на Roslyn — ты сильно удивишься, "я гарантирую это!" (С)

P>Легко — вся документация по одата протоколу открыта.

Не нужен весь протокол, ткни меня в пару структур, на которых можно устроить замеры.
(ты-то делал по работе, а у меня тут факультатив)
И дай, плиз, соотв данные — ведь ты как-то замерял, чтобы делать выводы, что у тебя оно работает быстрее.

Предлагаю тут чуток посотрудничать, разве тебе самому не интересно сравнить?
Re[13]: Лялих муст дие
Здравствуйте, Pauel, Вы писали:

V>>Разница есть, дотнет в виндах использует IOCP в асинхронщине в родном режиме проактора, а в линухах epoll в его режиме реактора.

V>>Первая технология заруливает вторую.
P>На замерах этого не видно — вот я тебе и пишу — линукс стабильно быстрее винды.

На замерах ноды?
Продолжаешь троллить...


V>>И какая в опу "очередь", кстате?

V>>Это у твоей ноды однопоточная очередь, в дотнете пул потоков.
P>А ты "специалист". "однопоточная очередь" В ноде тоже пул потоков, только оркестрируется из js-ного.

В ноде пул потоков IO, но события перенаправляются в одну JS-очередь.
Мы это уже разбирали не раз, заканчивай наводить тень на плетень. ))


P>Если у нас идет 100 коннектов, а ядер всего 8, то запросы будут большей частью висеть в очереди, ибо все ядра заняты, что в дотнете, что в ноде.


Да не будут в Windows висеть, в этом и прелесть.
Все эти запросы в проакторе могут обрабатывать одновременно, хоть тысячу их, независимо от кол-ва потоков и ядер.

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

Этот режим используется нодой в линухах и виндах.

Как работает проактор:
— в систему подаётся для чтения один или несколько буферов для приёма данных, ждём принятия этих данных;
— унутре ядра ОС происходят аппаратные прерывания от картеек по мере поступления физических пакетов из сети, данные из этих пакетов раскидываются по буферам; то бишь, многие тысячи коннектов могут принимать данные "одновременно" прямо на уровне ядра, без промежуточного буферирования в буфере сокета;
— прикладной колбэк вызывается уже по готовности данных, то бишь, из прикладного колбэка не требуется опять вызывать ф-ии ядра по чтению данных.

Таким образом, вместо использования буфера сокета, используется прикладные буфера, куда сразу пишутся данные.

Буфер сокета тоже может быть, куда будут складывать те данные, которое приложение не успевает выгребать, но при правильной организации, прикладные буфера ничем не отличаются от внутренних, поэтому смысла в них немного. В чём заключается "правильное использование буферов"? — в перекрывающемся (overlapped) IO. Пользовательский код может инициировать несколько операций IO с разными буферами, идеально будет 2-3 операции. Таким образом, пока текущие принятые данные обрабатываются приложением, ядро продолжает напихивать данными поданные буфера следующей инициированной операции. И вот так по кругу эти 2-3 операции крутятся, подставляя буфера для ядерного IO.

Именно через этот способ получается насытить данные 10-гигабитных картеек в Windows через одно соединение.
В Linux не получается никаким способом, они там в экспериментах насыщали десятком независимых соединений.

Двогонку, замечание про ноду.
С т.з. АПИ IO, нода выступает для прикладного программиста проактором, то бишь, прикладной программист инициирует операцию чтения и получает колбэк с уже принятыми данными.
Мои замечания к ноде к тому, как это организовано унутре — через режим реактора, то бишь, происходит лишняя перекачка данных.


V>>Давай разумного размера спецификацию JSON и тестовые данные, я тебе на коленке сделаю решение на .net core в единицы строк через кодогенерацию на Roslyn — ты сильно удивишься, "я гарантирую это!" (С)

P>Легко — вся документация по одата протоколу открыта.

Не нужен весь протокол, ткни меня в пару структур, на которых можно устроить замеры.
(ты-то делал по работе, а у меня тут факультатив)
И дай, плиз, соотв данные — ведь ты как-то замерял, чтобы делать выводы, что у тебя оно работает быстрее.

Предлагаю в этом вопросе чуток посотрудничать, разве тебе самому не интересно посмотреть/сравнить?
Ты ж сидел долго на дотнете, т.е. тебе должно быть как минимум любопытно.