Re[8]: Зачем нам асинхронность?
От: Mystic Artifact  
Дата: 07.08.20 10:12
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S>>> ValueTask

S>>>https://habr.com/ru/post/458828/
MA>> Что я должен нового узнать на этом недосайте?
S>

S>Вместо запуска какой-то задачи, в асинхронном методе вполне может лежать синхронный IPC с возвратом Task с результатом, который появится потом.


S>Если часто возвращаются FromResult kучше возвращать ValueTask так как нет затрат на размещение в куче.


Отвечать можно было не ссылкой, а несколькими своими словами, вот и всё. Неясно как это соотносится с изначальным вопросом/утверждением (на которое я отвечал), мне не совсем ясно, ну да ладно. Спасибо, что хотел подсказать что-то полезное.

Синхронный IPC — имелся ввиду синхронный вызов (постановка запроса) — по факту просто вызов метода библиотеки. Получение ответа разумеется асинхронное (по факту сообщение из очереди или колбэк из библиотеки). Я возможно неудачно выразился, но суть была в том, что асинхронный метод сам может и не выполнять никаких действий действий с пулом потоков и к нему никак не привязан.
Re[8]: Зачем нам асинхронность?
От: Sharov Россия  
Дата: 07.08.20 23:37
Оценка:
Здравствуйте, alex_public, Вы писали:

O>>Все с точностью до наоборот. Внутри винды весь ИО асинзронен, есть асинхронное АПИ — оно более "нативно", есть синхронное — оно внутри реализовано через асинхронное + ожидание его завершения.

_>Какие забавные фантазии. С большим интересом послушаю о том, как именно реализован прямой асинхронный вызов из драйвера сетевой карты (для примера) в спящий iocp поток нашего приложения.

Как-то так -- https://blog.stephencleary.com/2013/11/there-is-no-thread.html
Кодом людям нужно помогать!
Re[4]: Зачем нам асинхронность?
От: Sharov Россия  
Дата: 07.08.20 23:42
Оценка:
Здравствуйте, namespace, Вы писали:

N>А с нынешним async-await как мы управляем созданием потоков? Никак. Что там с потоком(из threadpoll) происходит, пока идет запись в сеть или на диск — непонятно. Висит впустую, ест ресурсы почем зря.


В том-то и дело, что нет. Поток возвращается в пул.
Кодом людям нужно помогать!
Re[9]: Зачем нам асинхронность?
От: Cyberax Марс  
Дата: 08.08.20 00:13
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

L>>Превосходить-то они превосходят, только вот если их еще и пытаться излишне параллелить, то переключения контекста тоже начнут отжирать приличную часть времени.

ЕМ>Чтобы переключения контекста стали отжирать приличную часть времени, их нужно сделать тысячи раз в секунду.
Это не так уж и сложно получить. Сотня потоков с квантом планирования в 10 миллисекунд дадут 10 тысяч переключений контекста в секунду.
Sapienti sat!
Re[10]: Зачем нам асинхронность?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.20 10:27
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Сотня потоков с квантом планирования в 10 миллисекунд дадут 10 тысяч переключений контекста в секунду.


Если каждый будет использовать квант полностью, то переключений будет сто в секунду. А если они будут переключаться принудительно и вхолостую, то хватит и двух потоков, чтобы создать десятки-сотни тысяч переключений в секунду.

А на реальных задачах, если умышленно не стремиться к искусственным частым переключениям, нужны весьма особые условия, чтобы накладные расходы от переключений стали заметны.
Re[6]: Зачем нам асинхронность?
От: alex_public  
Дата: 08.08.20 14:22
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>_

_>>А вот для случая привнесения "пользовательской асинхронности" (т.е. когда грубо говоря задача на закачку файла не блокирует весь UI до её исполнения) как раз правильнее использовать классический запуск фонового потока.
S>И чем это лучше?
S>Вместо awaite File.ReadAllTextAsync нужно создавать бэкграунд поток, передавать в него метод в котором вызывать в итоге File.ReadAllText

Потому что для однопользовательского случая такая задача масштабируется гораздо лучше.
Re[9]: Зачем нам асинхронность?
От: alex_public  
Дата: 08.08.20 14:30
Оценка: +2
Здравствуйте, Евгений Музыченко, Вы писали:

_>>Вот в древнем apache как раз именно так и считали, что нет смысла об этом думать. Только вот после выхода nginx'а (автор которого придерживался прямо противоположной точки зрения), почему то все серьёзно нагруженные сайты резко перебежали на него. )))

ЕМ>Я не смотрел код Apache, но, судя по функциональности, структуре конфигурационных файлов, способам управления и т.п., там уже давно сам черт ногу сломит. Вряд ли проблемы с его производительностью непосредственно связаны с затратами на переключение контекста.

Именно с этим. ) Во всяком случае в прошлом, когда nginx завоёвывал рынок. Сейчас то и у apache вроде есть возможность включить режим аналогичный nginx, так что сейчас разница действительно уже скорее от качества кода. А вот в прошлом именно поддержка асинхронного ввода-вывода (а конкретно функции epoll) позволила nginx занять доминирующее положение на рынке высоконагруженных сервисов.
Re[9]: Зачем нам асинхронность?
От: alex_public  
Дата: 08.08.20 14:55
Оценка: -1
Здравствуйте, ononim, Вы писали:

O>>>Все с точностью до наоборот. Внутри винды весь ИО асинзронен, есть асинхронное АПИ — оно более "нативно", есть синхронное — оно внутри реализовано через асинхронное + ожидание его завершения.

_>>Какие забавные фантазии. С большим интересом послушаю о том, как именно реализован прямой асинхронный вызов из драйвера сетевой карты (для примера) в спящий iocp поток нашего приложения.
O>Работа с сетью через IOCP это и есть едва ли не сферический пример юзания асинхронного АПИ, что сказать-то хотели?

Сказать хотел, что никаких реальных асинхронных вызовов там нет. Вот железо действительно асинхронно (см. прерывания), драйверы винды тоже (собственно они в итоге прерывания и обрабатывают), а вот далее вся асинхронность резко кончается. В пользовательском процессе у нас наблюдается тот же самый банальный поток, ждущий сообщения из очереди. Более того, в случае обслуживания одной операция ввода-вывода аналогичный код через синхронный АПИ будет скорее всего ещё и эффективнее, т.к. там будет просто разблокировка примитива синхронизации, без всяких игр с очередями.
Re[9]: Зачем нам асинхронность?
От: alex_public  
Дата: 08.08.20 15:08
Оценка: 1 (1)
Здравствуйте, Sharov, Вы писали:

O>>>Все с точностью до наоборот. Внутри винды весь ИО асинзронен, есть асинхронное АПИ — оно более "нативно", есть синхронное — оно внутри реализовано через асинхронное + ожидание его завершения.

_>>Какие забавные фантазии. С большим интересом послушаю о том, как именно реализован прямой асинхронный вызов из драйвера сетевой карты (для примера) в спящий iocp поток нашего приложения.
S>Как-то так -- https://blog.stephencleary.com/2013/11/there-is-no-thread.html

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

И да, если тебе реально интересно, как оно работает в деталях, то советую ознакомиться вот с этой https://docs.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports документацией.
Re[10]: Зачем нам асинхронность?
От: Sharov Россия  
Дата: 08.08.20 15:17
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Забавная статья. В ней всё абсолютно правильно, кроме первого абзаца (ты видимо только его и прочитал?), в котором автор радостно заявляет, что никаких ждущих потоков нет, и потом явно показывает их наличие в статье.


Подождите, автор говорил про iocp потоки пула, как результат работы io на самом верху (механизм передачи результата).
А кто сказал, что эти потоки ждут? Сам факт нахождения их в пуле говорит об обратном -- это всего лишь способ
диспетчеризации результата io в приложение. Т.е. iocp поток это не самый обычный поток, скажем так.
Кодом людям нужно помогать!
Re[7]: Зачем нам асинхронность?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.08.20 15:21
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, Serginio1, Вы писали:


S>>_

_>>>А вот для случая привнесения "пользовательской асинхронности" (т.е. когда грубо говоря задача на закачку файла не блокирует весь UI до её исполнения) как раз правильнее использовать классический запуск фонового потока.
S>>И чем это лучше?
S>>Вместо awaite File.ReadAllTextAsync нужно создавать бэкграунд поток, передавать в него метод в котором вызывать в итоге File.ReadAllText

_>Потому что для однопользовательского случая такая задача масштабируется гораздо лучше.

И чем это лучше? Ты запускаешь отдельный поток. Который нихрена не делает, только ожидает когда данные считаются. При этом морозит вспомогательный поток через объекты синхронизации до получения данных. При получении данных передает данные в основной поток.
При awaite File.ReadAllTextAsync данные передаются сразу в главный поток или если использовать .ConfigureAwaite(false) в любой поток.
Чем это маштабируется то лучше?
https://stackoverflow.com/questions/47741546/is-an-iocp-a-thread-that-is-running-while-the-i-o-is-taking-place-or-after
и солнце б утром не вставало, когда бы не было меня
Отредактировано 08.08.2020 17:28 Serginio1 . Предыдущая версия . Еще …
Отредактировано 08.08.2020 15:37 Serginio1 . Предыдущая версия .
Отредактировано 08.08.2020 15:29 Serginio1 . Предыдущая версия .
Re[10]: Зачем нам асинхронность?
От: ononim  
Дата: 08.08.20 15:37
Оценка: +1
_>Сказать хотел, что никаких реальных асинхронных вызовов там нет. Вот железо действительно асинхронно (см. прерывания), драйверы винды тоже (собственно они в итоге прерывания и обрабатывают), а вот далее вся асинхронность резко кончается. В пользовательском процессе у нас наблюдается тот же самый банальный поток, ждущий сообщения из очереди.
Асинхронность состоит в том, что пользовательский поток вовсе не обязан все время ждать сообщения. Он может заниматься чем-то другим и периодияеки обрабатывать что там ему наприходило.
Как много веселых ребят, и все делают велосипед...
Re[10]: Зачем нам асинхронность?
От: ononim  
Дата: 08.08.20 15:38
Оценка: +3
_>Забавная статья. В ней всё абсолютно правильно, кроме первого абзаца (ты видимо только его и прочитал?), в котором автор радостно заявляет, что никаких ждущих потоков нет, и потом явно показывает их наличие в статье.
А ты видимо из тех коментаторов статьи которые путают APC и DPC, да?
В статье объясняется что инициация асинхронной ио операции не требует постоянного выделения некоего потока для его обработки — ни в юзер моде ни в ядре.
Тот поток который запустил асинхронную ио операцию волен делать что угодно, а не только ждать ее исполнения. К примеру он может запустить еще десяток-два таких же, но других, операций, потом помайнить немного биткоинов и потом лишь проверить результат исполнения запущенных ио операций. В этом-то и состоит асинхронность.
Как много веселых ребят, и все делают велосипед...
Отредактировано 08.08.2020 16:00 ononim . Предыдущая версия .
Re[11]: Зачем нам асинхронность?
От: ononim  
Дата: 08.08.20 17:22
Оценка: 1 (1)
ЕМ>А на реальных задачах, если умышленно не стремиться к искусственным частым переключениям, нужны весьма особые условия, чтобы накладные расходы от переключений стали заметны.
Я както делал application-level виртуализацию под винду. Виртуальный реестр, фс и вот это вот все. Была выбрана а-ля микроядерная архитектура — отдельный процесс, который хостит реестр и фс (и еще кучу всякого делает) а в апликухах клиентских — Ntdll вся обхучена с ног до головы, и дерает через IPC процесс-ядро.
Вобщем оно все работало, но конечно IPC давало заметные накладные расходы. Причем IPC было самопальное, оптимизированное вусмерить. Данные ходили через shared memory, причем количество копирований данных было сведено к необходимому минимуму. Последней оптимизацией, которая дала значительный прирост, был следующих финт ушами: для IPC был добавлен свой _драйвер_, который при переключении контекста client->server насильно выставлял affinity потока-обработчика так, чтобы он начал исполняться на том же CPU, на котором работает поток-requestor. Это дало почти двукратный рост скорости IPC на мелких запросах.
Помню я тогда еще удивился — вот есть же такая замечательная функция — SignalObjectAndWait, для которой есть спец-сисколл ZwSignalAndWaitForSingleObject. Вот почему она такую оптимизацию из коробки не делает?
ЗЫ Факт пользы от этого трююка был многократно подтвержден на разных конфигурациях и разных виндах, начиная от ХР, под которую оно изначально было сделано, и заканчивая семеркой. Под десяткой уже не сравнивали — не до того было)
Как много веселых ребят, и все делают велосипед...
Re[11]: Зачем нам асинхронность?
От: alex_public  
Дата: 08.08.20 19:52
Оценка: 2 (1)
Здравствуйте, Sharov, Вы писали:

_>>Забавная статья. В ней всё абсолютно правильно, кроме первого абзаца (ты видимо только его и прочитал?), в котором автор радостно заявляет, что никаких ждущих потоков нет, и потом явно показывает их наличие в статье.

S>Подождите, автор говорил про iocp потоки пула, как результат работы io на самом верху (механизм передачи результата).

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

Вообще в этой области есть три классических подхода:

1. блокировка (до выполнения задачи)
2. опрос (о статусе выполнения задачи)
3. асинхронный вызов (коллбэк)

Так вот асинхронный ввод-вывод в винде иногда по незнанию позиционируют как третий вариант, но на самом деле там чисто второй, только слегка закумуфлированный. В линухе тоже самое (epoll), но они хотя бы честно говорят об этом, а не пытаются создать видимость настоящей асинхронности. Хотя в теории могли бы, т.к. в самой ОС присутствует механизм для подобных вызовов в пользовательском пространстве (сигналы), но для ввода-вывода он не используется. А вот реально асинхронный ввод-вывод сейчас можно пощупать руками наверное только при программирование МК (ну или написания своей ОС, но этим уже немногие занимаются).

S>А кто сказал, что эти потоки ждут? Сам факт нахождения их в пуле говорит об обратном -- это всего лишь способ

S>диспетчеризации результата io в приложение. Т.е. iocp поток это не самый обычный поток, скажем так.

Ты похоже невнимательно прочитал документацию по IOCP. )
Re[8]: Зачем нам асинхронность?
От: alex_public  
Дата: 08.08.20 20:05
Оценка: -1
Здравствуйте, Serginio1, Вы писали:

S>>>Вместо awaite File.ReadAllTextAsync нужно создавать бэкграунд поток, передавать в него метод в котором вызывать в итоге File.ReadAllText

_>>Потому что для однопользовательского случая такая задача масштабируется гораздо лучше.
S> И чем это лучше? Ты запускаешь отдельный поток. Который нихрена не делает, только ожидает когда данные считаются.

И в чём проблема с этим? ) Речь же не про тысячу таких потоков, а про один. )

S>При этом морозит вспомогательный поток через объекты синхронизации до получения данных.


С чего бы это?

S> При awaite File.ReadAllTextAsync данные передаются сразу в главный поток или если использовать .ConfigureAwaite(false) в любой поток.

S> Чем это маштабируется то лучше?

Потому что помимо просто чтения файла в реальном мире у тебя будет ещё и какая-то его минимальная обработка. Например его парсинг. Если использовать твою схему с awaite File.ReadAllTextAsync, где по твоему будет происходить обработка? Если изначальный вызов был у тебя в UI потоке, то и обработка пойдёт там же. И это даже будет нормально работать у тебя на небольших файликах. А потом пользователь загрузит туда гигабайтный файл и всё твоё приложение зависнет на неопределённое время. А для варианта с отдельным потоком, никаких проблем не будет — просто подольше будет идти обработка, но без всяких зависаний приложения.

Ты сейчас наверное скажешь, что правильный программист сразу же выделит парсинг в отдельный поток, как потенциально длительную операцию. Вот только тогда сразу появляется простейший вопрос: а зачем нам тогда нужен асинхронный ввод-вывод, если у нас и так создаётся поток под эту задачу?
Re[11]: Зачем нам асинхронность?
От: alex_public  
Дата: 08.08.20 20:17
Оценка: :)
Здравствуйте, ononim, Вы писали:

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

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

Вообще то GetQueuedCompletionStatus вполне себе ждёт сообщения, если их нет в очереди. )))
Re[12]: Зачем нам асинхронность?
От: ononim  
Дата: 08.08.20 20:22
Оценка: 1 (1)
O>>Асинхронность состоит в том, что пользовательский поток вовсе не обязан все время ждать сообщения. Он может заниматься чем-то другим и периодияеки обрабатывать что там ему наприходило.
_>Вообще то GetQueuedCompletionStatus вполне себе ждёт сообщения, если их нет в очереди. )))

if dwMilliseconds is INFINITE, the function will never time out. If dwMilliseconds is zero and there is no I/O operation to dequeue, the function will time out immediately.

(c)
Но конечно же так делать далеко не всегда оптимальная стратегия. Но вполне реальная. К примеру имеем видеокодер реального времени (с видеокамеры) с внутренним буфером который он иногда сбрасывает на диск. Типа накодировал себе 16 мегабайт — проверил что предыдущая запись завершилась, и если да — запустил асинхронный сброс текущего буфера, а если нет — ну значит отращиваем буфер для следующей порции видео, видеокамера то ждать не будет.
Но обычно эффективнее таки ждать вечно когда делать больше нечего. Имеем распаковщик архивов — он запускает асинхронное чтение, и запустив — занимается декодированной порции данных прочитанных операцией стартованной в предыдущей итерации. Как декодировали — ждем довычитки порции данных, запускаем новую операцию на будущее и декодируем нововычитанные данные.
Но на самом деле самое интересное что можно запустить 100500 IO операций. В случае чтения с различных мест (разных файлов, разных мест однго и того же файла) это позволяет IO manager'у оптимальным образом группировать запросы в NCQ. Если кончено он умеет
Как много веселых ребят, и все делают велосипед...
Отредактировано 08.08.2020 20:30 ononim . Предыдущая версия . Еще …
Отредактировано 08.08.2020 20:23 ononim . Предыдущая версия .
Re[11]: Зачем нам асинхронность?
От: alex_public  
Дата: 08.08.20 20:37
Оценка: 1 (1)
Здравствуйте, ononim, Вы писали:

_>>Забавная статья. В ней всё абсолютно правильно, кроме первого абзаца (ты видимо только его и прочитал?), в котором автор радостно заявляет, что никаких ждущих потоков нет, и потом явно показывает их наличие в статье.

O>А ты видимо из тех коментаторов статьи которые путают APC и DPC, да?

Ну раз ты так считаешь, что конечно же укажешь место в моих сообщениях, где я их спутал? )

O>В статье объясняется что инициация асинхронной ио операции не требует постоянного выделения некоего потока для его обработки — ни в юзер моде ни в ядре.

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

Нет, не может, потому как и в данной статье и в данной темке обсуждается не абстрактный асинхронный ввод-вывод в винде, а вполне конкретная реализация его из .net. И в ней для IOCP используется специальный пул потоков, который только этим и занимается. Никто там руками не забирает сообщения из очереди IOCP и не смешивает такой код с пользовательскими вычислениям. Так что в случае только одной операции ввода-вывода в каждый момент времени, не будет ни малейшего отличия от синхронного ввода-вывода (с запуском отдельного потока), ну не считая выполнения кучи ненужного сервисного кода с очередями и т.п. в случае IOCP.
Re[12]: Зачем нам асинхронность?
От: ononim  
Дата: 08.08.20 20:46
Оценка:
_>>>Забавная статья. В ней всё абсолютно правильно, кроме первого абзаца (ты видимо только его и прочитал?), в котором автор радостно заявляет, что никаких ждущих потоков нет, и потом явно показывает их наличие в статье.
O>>А ты видимо из тех коментаторов статьи которые путают APC и DPC, да?
_>Ну раз ты так считаешь, что конечно же укажешь место в моих сообщениях, где я их спутал? )
В твоих нет, но в первых коментах к той статье там явно начали аргументировать что DPC — это обязательно поток, похоже коментатор исходил из предположения что DPC -это APC. Но это не так. APC — шедулится на поток, DPC шедулится на процессор.

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

_>Нет, не может, потому как и в данной статье и в данной темке обсуждается не абстрактный асинхронный ввод-вывод в винде, а вполне конкретная реализация его из .net. И в ней для IOCP используется специальный пул потоков, который только этим и занимается.
Ну, в внутренностях дотнетов я не копенгаген — б-г миловал. Но можно предположить что количество потоков в этом пуле максимум — соразмерно колву логических CPU. То есть все еще можно запустить 100500 операций — а количество потоков в пуле от этого не вырастет, просто они результаты будут все по-очереди разгребать. Условие "IO операция != поток" вполне выполняется.
Как много веселых ребят, и все делают велосипед...
Отредактировано 08.08.2020 20:47 ononim . Предыдущая версия . Еще …
Отредактировано 08.08.2020 20:47 ononim . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.