Re[25]: Зачем нам асинхронность?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 25.08.20 10:09
Оценка:
Здравствуйте, rameel, Вы писали:

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


S>>.NET 4.5 x64 i = 47_995_000 (array dimensions exceed supported range)

S>>.NET 4.5 x86 i = 23_997_000 (out of memory)

R>.NET Core 5 Preview 7 x64

R>i = 767_933_000
R>Out of memory.

Можно попробовать
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();



https://docs.microsoft.com/ru-ru/dotnet/api/system.runtime.gcsettings.largeobjectheapcompactionmode?view=netcore-3.1
и солнце б утром не вставало, когда бы не было меня
Re[26]: Зачем нам асинхронность?
От: Mystic Artifact  
Дата: 25.08.20 12:56
Оценка: 1 (1) +1
Здравствуйте, Sharov, Вы писали:

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


Зато там есть SetMinThreads, который раньше по моему было в 10 потоков и любой консольный хэллоу ворд их создавал... просто так. На текущих фреймворках не проверял / смотрел давно.
Re[26]: Зачем нам асинхронность?
От: Ночной Смотрящий Россия  
Дата: 25.08.20 13:00
Оценка: -1
Здравствуйте, Sharov, Вы писали:

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


Откуда у вас такие странные идеи? Я такое видел только в плюсовом коде с рукопашной реализацией пула, заточенного под специфические сценарии. Поднимать пачку потоков при старте любого приложения заранее?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[27]: Зачем нам асинхронность?
От: Sharov Россия  
Дата: 25.08.20 14:17
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, Sharov, Вы писали:


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


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


1) Я написал откуда.
2) Возможно создание потоков во время работы приложения является неприемлемым, поэтому лучше заранее об этом позаботиться. Мало ли сценариев.
3) На сколько я понимаю, пул потоков и так поднимает >1 при старте.
Кодом людям нужно помогать!
Re[23]: Зачем нам асинхронность?
От: alex_public  
Дата: 25.08.20 16:03
Оценка: -2
Здравствуйте, Sinclair, Вы писали:

_>>Ха, случай "десятка-другого" потоков — это как раз наоборот пример идеальной производительности потокового решения, т.к. у нас количество задач будет приблизительно равно числу ядер процессора.

S>Хм, мы сейчас про десктоп или про сервер? На моём лаптопе 4 (четыре) ядра.

Не знаю зачем ты работаешь на десктопе из 2000-ых. А вот в наше время минимальная конфигурация — это 12 логических ядер (https://market.yandex.ru/product--protsessor-amd-ryzen-5-3600/508275153). Нормальный конфиг — это 24 логических ядра (https://market.yandex.ru/product--protsessor-amd-ryzen-9-3900x/508252149), а топовый уже 32 логических ядра (https://market.yandex.ru/product--protsessor-amd-ryzen-9-3950x/508275148). Ну точнее есть ещё решения класса HEDT, в которых дошли уже до 128 ядер (https://market.yandex.ru/product--protsessor-amd-ryzen-threadripper-3990x/662911002), но это уже явно игрушка не для всех.

И да, все выше перечисленные процессоры (включая threadripper) — это не серверные решения!

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

S>Давайте посмотрим в таск менеджер. Вот у меня на лаптопе прямо сейчас работают 3992 потока.
S>Приложение же работает не в вакууме — а вы пишете так, как будто кроме ваших потоков, никаких других нет.

И 99,9% этих потоков спит, никому не мешая. Проблемы возникают только тогда, когда у нас есть тысячи потоков, между которыми надо реально постоянно переключаться.

S>В реальности автор каждого говноприложения думает именно так — "нафига мне все эти задурения, полсотни потоков планировщик прожуёт не задумываясь", и в итоге мы имеем то, что имеем — пять-десять тысяч потоков, которые, по большому счёту не нужны.


Так он реально "прожуёт не задумываясь" и всё будет отлично работать. )))

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

P.S. Кстати, с твоим мышлением тебе бы надо было держаться подальше от .Net, с учётом того, сколько там запускается всяческих сервисных потоков для каждого приложения. )))
Re[21]: Зачем нам асинхронность?
От: alex_public  
Дата: 25.08.20 16:11
Оценка:
Здравствуйте, Mystic Artifact, Вы писали:

_>>А что такое традиционные решения?

MA> Указатели, псевдо-указатели в пул/регион, смарт поинтеры и в тяжелых случаях GC ссылки. Последние 3 не бесплатные. Все 4 вполне широко применяются в C++.

Ну так всё это же доступно и в Rust. Только для некоторых требуется использование блоков unsafe. Собственно очень многие инструменты из стандартной библиотеки языка или популярных пакетов внутри реализованы именно через классический "C++ код", внутри unsafe блока. Но зато наружу они экспортируют "чистые" от ошибок памяти интерфейсы (при условии что внутри этих unsafe блоков не было ошибок ).

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

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

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

P.S. Кстати, у меня лично тоже есть множество задач, для которых в Rust'е без unsafe делать нечего. Но я осознаю, что они тоже далеки от стандартного (например управление периферией микроконтроллеров).
Re[22]: Зачем нам асинхронность?
От: Mystic Artifact  
Дата: 25.08.20 16:46
Оценка:
Здравствуйте, alex_public, Вы писали:

Разве я говорю, что что-то в Rust что-то невозможно или недоступно?.. (риторический вопрос)

_>Нуу на мой личный вкус это скорее у тебя какие-то нестандартные задачи. Для обычного прикладного кода я не вижу особых причин натыкаться на ругань компилятора.

Так в обычных задачах достаточно и обычных ссылок в перемешку с константностью. Там где borrowing работает — там и человек справляется (на C++). А там где он не работает — абсолютно все равно. Тем не менее, это подается под соусом безопасности, которой на самом деле нет. Спрпведливости ради, приблизительно так же поданы и C#/Java которые точно так же имеют очень ограниченное понимание безопасности как таковой.

_>P.S. Кстати, у меня лично тоже есть множество задач, для которых в Rust'е без unsafe делать нечего. Но я осознаю, что они тоже далеки от стандартного (например управление периферией микроконтроллеров).

Да это нормально для любого инфраструктурного кода. В C# благо есть unsafe, благодаря которому можно делать некоторые вещи эффективно. Понятное дело, что в клиентском коде этому не место.

PS: Я не думаю что тут нужно продолжать. Мне нравятся многие идеи в Rust. Но, он, имхо, спозиционирован несколько альтернативно в этом мире, и порою через чур агрессивно. Почему-то даже пакеты называются ящиками. Но это уже из области иррационального.
Re[24]: Зачем нам асинхронность?
От: Mystic Artifact  
Дата: 25.08.20 17:05
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Не знаю зачем ты работаешь на десктопе из 2000-ых.

Ноутбук. У моего например проц постарше но тоже 4 ядра. А на десктопе я использую более древний i7-4770 и пока всем устраивает. Там где можно выиграть от 32 ядер — задача есть у меня, но она пока разрешима без оборудования. (Билд сервер и так имеет 32 ядра, а локально можно потерпеть пока горячие билды занимают менее минуты.)

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

S>>Приложение же работает не в вакууме — а вы пишете так, как будто кроме ваших потоков, никаких других нет.
У меня там обычно цифра под 10К потоков. В целом не мешают, но... нахер оно нужно тоже неронятно. Но это воппос не о архитектуре приложений, а скорее вопрос к винде. Я уже давно перестал отключать ненужные сервисы. Но сейчас опять модно-хипстериски — создавать сервисы на лету. На кой хер оно нужно винде я не знаю.

_>Так он реально "прожуёт не задумываясь" и всё будет отлично работать. )))

Ровно до того момента пока ресурсы свободны. Когда же мы бросаем такое приложение в ситуацию когда CPU нагружен на 100% — ситуация меняется кардинально. Но это часто вопрос дизайна самих приложений (в том плане, что они создаются потреблять имеющиеся ресурсы — проблема возникает только когда они думают, что они имеются, а по факту нет). Так что в целом согласен.

_>Да, и вообще говоря, чем более распараллелено твоё приложение, тем лучше. Потому как рост быстродействия современных процессоров в расчёте на одно ядро уже давно прекратился и увеличение производительности сейчас идёт только за счёт увеличения числа ядер.

А это очень непросто. Куча задач не хотят параллелится на десктопе. Тем не менее возможно. Но... имхо, щас как-то все позабыли даже о IO/HDD, взять студию — она принимает идиотские стратегические решения. В итоге простое сохранение файла на диск может вызывать длительные похрюкивания. Я уже не говорю о том, что временные каталоги она создает по любым доступным дискам. Зачем... есть же темп.

_>P.S. Кстати, с твоим мышлением тебе бы надо было держаться подальше от .Net, с учётом того, сколько там запускается всяческих сервисных потоков для каждого приложения. )))

И сколько же? Посчитай внимательно, их ровно столько сколько попросит пользователь.
Re[25]: Зачем нам асинхронность?
От: alex_public  
Дата: 25.08.20 21:07
Оценка:
Здравствуйте, Mystic Artifact, Вы писали:

_>>Не знаю зачем ты работаешь на десктопе из 2000-ых.

MA> Ноутбук. У моего например проц постарше но тоже 4 ядра. А на десктопе я использую более древний i7-4770 и пока всем устраивает. Там где можно выиграть от 32 ядер — задача есть у меня, но она пока разрешима без оборудования. (Билд сервер и так имеет 32 ядра, а локально можно потерпеть пока горячие билды занимают менее минуты.)

Ну так i7 — это уже минимум 8 логических ядер. А по поводу "всем устраивает" — это как раз то самое, что я уже говорил здесь. Быстродействие процессоров в расчёте на ядро уже довольно давно не растёт (ну рост на пару процентов за поколение мы не считаем), так что если нужное тебе ПО не умеет во много потоков, то и смысла апгрейдиться нет. Но сейчас уже многое ПО умеет, особенно в области разработки.

_>>Да, и вообще говоря, чем более распараллелено твоё приложение, тем лучше. Потому как рост быстродействия современных процессоров в расчёте на одно ядро уже давно прекратился и увеличение производительности сейчас идёт только за счёт увеличения числа ядер.

MA> А это очень непросто. Куча задач не хотят параллелится на десктопе. Тем не менее возможно. Но... имхо, щас как-то все позабыли даже о IO/HDD, взять студию — она принимает идиотские стратегические решения. В итоге простое сохранение файла на диск может вызывать длительные похрюкивания. Я уже не говорю о том, что временные каталоги она создает по любым доступным дискам. Зачем... есть же темп.


Да, то что сейчас настало время писать параллельный софт (иначе просто не сможешь использовать возможности железа) совпало с расцветом "индусокода" — это конечно же будет тяжёлое испытания для индустрии. )))

_>>P.S. Кстати, с твоим мышлением тебе бы надо было держаться подальше от .Net, с учётом того, сколько там запускается всяческих сервисных потоков для каждого приложения. )))

MA> И сколько же? Посчитай внимательно, их ровно столько сколько попросит пользователь.

Мда? ) А как же там всякие потоки для финализаторов, таймеров и т.п.? ) И да, я в таком ужасе как WPF не копался, но помнится мне один знакомый говорил, что у него там на пустом приложение (ну в смысле с какой-то базовой формочкой) автоматом 10 потоков стартует.
Re[8]: Зачем нам асинхронность?
От: vdimas Россия  
Дата: 25.08.20 22:13
Оценка: 1 (1)
Здравствуйте, alex_public, Вы писали:

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


У асинхронных операций сложилось 3 основных способа общения с внешним миром:
— через опрос состояния операции;
— через установку связанного с операцией некоего примитива сигнализации;
— через колбэки.
Re[26]: Зачем нам асинхронность?
От: Mystic Artifact  
Дата: 25.08.20 23:38
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Ну так i7 — это уже минимум 8 логических ядер. А по поводу "всем устраивает" — это как раз то самое, что я уже говорил здесь. Быстродействие процессоров в расчёте на ядро уже довольно давно не растёт (ну рост на пару процентов за поколение мы не считаем), так что если нужное тебе ПО не умеет во много потоков, то и смысла апгрейдиться нет. Но сейчас уже многое ПО умеет, особенно в области разработки.

Ну и тем не менее довольно давно можно получить 4ГГц, в то время как мои питомцы дуют 3 с лишнем только в турбо. Да, это не предел, и в сущности, часто, как я думаю можно упереться в память. Вдобавок, новые стандарты DDR походу только называются красиво, а могут добавить ровно ноль. По крайней мере сложилось такое впечатление о DDR4. А вообще я тут и не спорил. Я сюда вступил в эту подветку, исключительно с мыслью, что старое оборудование вполне себе и ничего. К сожалению мысль не донёс.

_>Да, то что сейчас настало время писать параллельный софт (иначе просто не сможешь использовать возможности железа) совпало с расцветом "индусокода" — это конечно же будет тяжёлое испытания для индустрии. )))

Мне это чаще видится досадным оверинжинирингом. Я вполне себе отдаю отчет, что, что-то может быть сделано не так, чем я думаю... Но порою я не вижу логики. Блин. В VS Code — не работает системное меню окна. Они просто рисуют там иконку и так с рождения. А я вот пользуюсь. Юзабилити? Не, не слышали. И так с самого начала. Может ты и прав насчет индусятины. (Ведь спустя года ничего не поправили.)

MA>> И сколько же? Посчитай внимательно, их ровно столько сколько попросит пользователь.

_>Мда? ) А как же там всякие потоки для финализаторов, таймеров и т.п.? ) И да, я в таком ужасе как WPF не копался, но помнится мне один знакомый говорил, что у него там на пустом приложение (ну в смысле с какой-то базовой формочкой) автоматом 10 потоков стартует.
Ну я вообще от тебя хотел услышать. Основные потоки лезут от GC в зависимости от его режима. Никто не заставляет использовать фоновую и/или серверный GC. Тем не менее не стоит серверный выкидывать из игры. У меня в одной консольной тулзе не удалось нагрузить потоками проц более 50-60%. Просто переключение в серверный GC это дает сделать тому же коду, при чем пиковое потребление памяти становится даже меньше. (Хотя обычно серверный гц как раз кушает память более охотно.)
Я рядом уже писал про minthreads. Я не знаю с какой версии это пошло и в какой кончилось. В текущих .net core можно наблюдать <10 потоков.
PS: И могу ошибаться, но минимальное число потоков должно было конфигурироваться ч/з конфиг, или только ч/з хост? Честно говоря конкретно этим вопросом давно не парился, видел только улучшения в лучшую сторону, но в детали не вникал.
Re[24]: Зачем нам асинхронность?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.08.20 05:48
Оценка: +3
Здравствуйте, alex_public, Вы писали:

_>Не знаю зачем ты работаешь на десктопе из 2000-ых.

Ну, так-то он вышел в Q3 2015. Intel Core i7-6600U CPU 2.60GHz (Skylake). Вполне себе современный процессор.
Вот что я планирую ему на замену: https://ark.intel.com/content/www/us/en/ark/products/149091/intel-core-i7-8565u-processor-8m-cache-up-to-4-60-ghz.html
4 (четыре) ядра.

_>А вот в наше время минимальная конфигурация — это 12 логических ядер (https://market.yandex.ru/product--protsessor-amd-ryzen-5-3600/508275153). Нормальный конфиг — это 24 логических ядра (https://market.yandex.ru/product--protsessor-amd-ryzen-9-3900x/508252149), а топовый уже 32 логических ядра (https://market.yandex.ru/product--protsessor-amd-ryzen-9-3950x/508275148). Ну точнее есть ещё решения класса HEDT, в которых дошли уже до 128 ядер (https://market.yandex.ru/product--protsessor-amd-ryzen-threadripper-3990x/662911002), но это уже явно игрушка не для всех.

Если мы посмотрим в мобильный сегмент, то там трудновато найти конфиг с количеством ядер больше 6. Вот примерно что ставится в типичный ноут бизнес-класса: https://www.amd.com/en/products/apu/amd-ryzen-5-4600h

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

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

_>И 99,9% этих потоков спит, никому не мешая. Проблемы возникают только тогда, когда у нас есть тысячи потоков, между которыми надо реально постоянно переключаться.
Ну нет конечно. Планировщик работает со всеми потоками сразу. Для него нет "спящих" потоков — именно он и решает, кого разбудить, а кого нет. Да, активные потоки нагружают его сильнее — и тем не менее, лишние 5-10 тысяч спящих потоков вполне заметно влияют на время, проводимое в ядре.

_>Так он реально "прожуёт не задумываясь" и всё будет отлично работать. )))



_>Да, и вообще говоря, чем более распараллелено твоё приложение, тем лучше. Потому как рост быстродействия современных процессоров в расчёте на одно ядро уже давно прекратился и увеличение производительности сейчас идёт только за счёт увеличения числа ядер.

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

_>P.S. Кстати, с твоим мышлением тебе бы надо было держаться подальше от .Net, с учётом того, сколько там запускается всяческих сервисных потоков для каждого приложения. )))

И сколько же?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Зачем нам асинхронность?
От: Sharov Россия  
Дата: 27.08.20 10:44
Оценка:
Здравствуйте, vdimas, Вы писали:

V>У асинхронных операций сложилось 3 основных способа общения с внешним миром:

V>- через опрос состояния операции;
V>- через установку связанного с операцией некоего примитива сигнализации;
V>- через колбэки.

Кстати, отличное наблюдение. Эти 3 способа коррелируют с моделями сети в теории распределенных систем -- асинхронной, синхронной и полу-синхронной.

https://decentralizedthoughts.github.io/2019-06-01-2019-5-31-models/

1)

In the Synchronous model, there exists some known finite time bound Δ.
For any message sent, the adversary can delay its delivery by at most Δ.


Это опрос состояния операции.

2)

In the Asynchronous model, for any message sent, the adversary can delay its delivery by any finite amount of time.
So, on the one hand, there is no bound on the time to deliver a message but, on the other hand, each message must eventually be delivered.


Это колбэки.

3)

The Partial synchrony model (see DLS88) aims to find a middle ground between these two models.
The assumption is that there exists some known finite time bound Δ and a special event called GST (Global Stabilization Time) such that:


Методом исключения это установка связанного с операцией некоего примитива сигнализации.
Кодом людям нужно помогать!
Re[12]: Зачем нам асинхронность?
От: vdimas Россия  
Дата: 27.08.20 12:41
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>Нет, не может, потому как и в данной статье и в данной темке обсуждается не абстрактный асинхронный ввод-вывод в винде, а вполне конкретная реализация его из .net. И в ней для IOCP используется специальный пул потоков, который только этим и занимается.


Пул потоков занимается не только IO, ты можешь пихать в него произвольные свои задачи:
https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.queueuserworkitem?view=netcore-3.1#System_Threading_ThreadPool_QueueUserWorkItem__1_System_Action___0____0_System_Boolean_

И это не дотнетная приблуда, а системная виндовая:
https://docs.microsoft.com/en-us/windows/win32/procthread/thread-pooling


_>Никто там руками не забирает сообщения из очереди IOCP и не смешивает такой код с пользовательскими вычислениям.


"Руками" забирать и не надо, есть дотнетное апи над виндовым thread pool.
Дотнет активно использует встроенный виндовый пул потоков как для новомодных дотнетных Task, так и для традиционного дотнетного асинхронного ввода-вывода.


_>Так что в случае только одной операции ввода-вывода в каждый момент времени


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


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


Как это "синхронного с запуском отдельного потока"? ))
Как передавать данные в тот поток из потока GUI и как получать результат?
Уже получится асинхронная схема.
Ну да, в до-WinXP времена так и надо было делать для асинхронщины в виндах — создавать IO-потоки и общаться с ними самостоятельно (как раз пришлось поупражняться в 98-2000-х годах)

Начиная с WinXP эти востребованные сценарии включили прямиков в Windows API, бо каждое виндовое GUI-приложение, того времени, работающее с сеткой, содержало свою асинхронную подсистему. Т.е., наличие completion routines (alertable IO) и CP — это всё понятно, но над этим требовалось выстраивать некую более высокоуровневую структуру, для автоматизации создания/запуска/остановки потоков, слежения за тем, чтобы случайно не прибить поток, который начал асинхронную операцию и т.д. и т.п. Ну вот винды все эти вещи автоматизировали.


_>ну не считая выполнения кучи ненужного сервисного кода с очередями и т.п. в случае IOCP.


Считая. ))
В твоей самописной системе, состоящей из "основного" и "асинхронного" потока, все-равно придётся делать две очереди (если по-уму) — от основного потока в поток IO, и обратно.

В дотнете подобные вещи автоматизированы через т.н. контекст исполнения. Например, в GUI потоке контекст требует отправлять продолжения задач обратно в этот же поток, поэтому, из IOCP-потока задача продолжена не будет, а будет своим обработчиком направлена в очередь GUI-потоку.

В общем, ты ничего на самописном синхронном IO не сэкономишь.
Отредактировано 27.08.2020 18:09 vdimas . Предыдущая версия .
Re[9]: Зачем нам асинхронность?
От: alex_public  
Дата: 27.08.20 15:05
Оценка:
Здравствуйте, vdimas, Вы писали:

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

V>У асинхронных операций сложилось 3 основных способа общения с внешним миром:
V>- через опрос состояния операции;
V>- через установку связанного с операцией некоего примитива сигнализации;
V>- через колбэки.

Основной нюанс тут в том, что для небольшого числа одновременных операций какие-то преимущества перед синхронным вариантом мог бы дать только третий вариант. Однако к сожалению ни одна ОС в данный момент не предоставляет такого интерфейса (а там где какая-то библиотека казалось бы его предоставляет, на самом деле имеется просто скрытый поток, сидящий на примитиве синхронизации).
Re[27]: Зачем нам асинхронность?
От: alex_public  
Дата: 27.08.20 15:20
Оценка:
Здравствуйте, Mystic Artifact, Вы писали:

_>>Ну так i7 — это уже минимум 8 логических ядер. А по поводу "всем устраивает" — это как раз то самое, что я уже говорил здесь. Быстродействие процессоров в расчёте на ядро уже довольно давно не растёт (ну рост на пару процентов за поколение мы не считаем), так что если нужное тебе ПО не умеет во много потоков, то и смысла апгрейдиться нет. Но сейчас уже многое ПО умеет, особенно в области разработки.

MA> Ну и тем не менее довольно давно можно получить 4ГГц, в то время как мои питомцы дуют 3 с лишнем только в турбо. Да, это не предел, и в сущности, часто, как я думаю можно упереться в память. Вдобавок, новые стандарты DDR походу только называются красиво, а могут добавить ровно ноль. По крайней мере сложилось такое впечатление о DDR4. А вообще я тут и не спорил. Я сюда вступил в эту подветку, исключительно с мыслью, что старое оборудование вполне себе и ничего. К сожалению мысль не донёс.

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

Но вот если твоё основное ПО поддерживает полноценное (а не в 2-3 потока) распараллеливание, то сейчас есть прямой смысл апгрейдиться чуть ли не через каждый год...

_>>Да, то что сейчас настало время писать параллельный софт (иначе просто не сможешь использовать возможности железа) совпало с расцветом "индусокода" — это конечно же будет тяжёлое испытания для индустрии. )))

MA> Мне это чаще видится досадным оверинжинирингом. Я вполне себе отдаю отчет, что, что-то может быть сделано не так, чем я думаю... Но порою я не вижу логики. Блин. В VS Code — не работает системное меню окна. Они просто рисуют там иконку и так с рождения. А я вот пользуюсь. Юзабилити? Не, не слышали. И так с самого начала. Может ты и прав насчет индусятины. (Ведь спустя года ничего не поправили.)

Хы, ты посмотри на апдейты Винды! Там с каждым разом всё больше и больше ломают разного. Новости об этом уже чуть ли не повседневные на "lenta.ru" и наверное скоро переместят в раздел юмора... )))

MA>>> И сколько же? Посчитай внимательно, их ровно столько сколько попросит пользователь.

_>>Мда? ) А как же там всякие потоки для финализаторов, таймеров и т.п.? ) И да, я в таком ужасе как WPF не копался, но помнится мне один знакомый говорил, что у него там на пустом приложение (ну в смысле с какой-то базовой формочкой) автоматом 10 потоков стартует.
MA> Ну я вообще от тебя хотел услышать. Основные потоки лезут от GC в зависимости от его режима. Никто не заставляет использовать фоновую и/или серверный GC. Тем не менее не стоит серверный выкидывать из игры. У меня в одной консольной тулзе не удалось нагрузить потоками проц более 50-60%. Просто переключение в серверный GC это дает сделать тому же коду, при чем пиковое потребление памяти становится даже меньше. (Хотя обычно серверный гц как раз кушает память более охотно.)
MA> Я рядом уже писал про minthreads. Я не знаю с какой версии это пошло и в какой кончилось. В текущих .net core можно наблюдать <10 потоков.
MA> PS: И могу ошибаться, но минимальное число потоков должно было конфигурироваться ч/з конфиг, или только ч/з хост? Честно говоря конкретно этим вопросом давно не парился, видел только улучшения в лучшую сторону, но в детали не вникал.

Не, я с этим вопросом вообще не разбирался (так то я .net вообще не использую в работе), поэтому здесь передаю чужие сведения. Хотя вполне авторитетные. Да и потоки таймеров с финализаторами сам видел при каких-то тестах в прошлом.

Да, и на всякий случай ещё раз уточню, что я не отношусь к "потокофобам" (типа Sinclair), поэтому собственно не вижу в этом ничего страшного. Но вот если бы я дрожал от каждого лишнего потока, то однозначно даже не приблизился бы к .net, потому как там их априори больше чем требуется для просто "потоков вычисления".
Re[25]: Зачем нам асинхронность?
От: alex_public  
Дата: 27.08.20 18:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Не знаю зачем ты работаешь на десктопе из 2000-ых.

S>Ну, так-то он вышел в Q3 2015. Intel Core i7-6600U CPU 2.60GHz (Skylake). Вполне себе современный процессор.
S>Вот что я планирую ему на замену: https://ark.intel.com/content/www/us/en/ark/products/149091/intel-core-i7-8565u-processor-8m-cache-up-to-4-60-ghz.html
S>4 (четыре) ядра.

Вообще то там 8 логических ядер. )

_>>А вот в наше время минимальная конфигурация — это 12 логических ядер (https://market.yandex.ru/product--protsessor-amd-ryzen-5-3600/508275153). Нормальный конфиг — это 24 логических ядра (https://market.yandex.ru/product--protsessor-amd-ryzen-9-3900x/508252149), а топовый уже 32 логических ядра (https://market.yandex.ru/product--protsessor-amd-ryzen-9-3950x/508275148). Ну точнее есть ещё решения класса HEDT, в которых дошли уже до 128 ядер (https://market.yandex.ru/product--protsessor-amd-ryzen-threadripper-3990x/662911002), но это уже явно игрушка не для всех.

S>Если мы посмотрим в мобильный сегмент, то там трудновато найти конфиг с количеством ядер больше 6. Вот примерно что ставится в типичный ноут бизнес-класса: https://www.amd.com/en/products/apu/amd-ryzen-5-4600h

А тут их 12. )))

S>Десктопы, как сегмент, постепенно отмирают. Потому что проигрывают по удобству использования лаптопам — их ни на конференцию не возьмешь, ни домой из офиса.


Лаптоп? фуфуфу — большая неудобная хреновина. Не сравнится по удобству работы с десктопом и по мобильности с планшетом. На конференции или встречи я обычно беру с собой планшетик.

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

_>>И 99,9% этих потоков спит, никому не мешая. Проблемы возникают только тогда, когда у нас есть тысячи потоков, между которыми надо реально постоянно переключаться.
S>Ну нет конечно. Планировщик работает со всеми потоками сразу. Для него нет "спящих" потоков — именно он и решает, кого разбудить, а кого нет. Да, активные потоки нагружают его сильнее — и тем не менее, лишние 5-10 тысяч спящих потоков вполне заметно влияют на время, проводимое в ядре.

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

_>>Да, и вообще говоря, чем более распараллелено твоё приложение, тем лучше. Потому как рост быстродействия современных процессоров в расчёте на одно ядро уже давно прекратился и увеличение производительности сейчас идёт только за счёт увеличения числа ядер.

S>Нет конечно, нет никакого "вообще говоря". Чрезмерная параллелизация только ухудшает производительность.

Безусловно чрезмерное число одновременно работающих потоков ухудшает производительность. Но чрезмерное в данном случае — это тысячи, а не сотни и уж точно не десятки.

S>Как раз IOCP позволяет эффективно использовать ядра, без дополнительных накладных расходов.


Дополнительные накладные расходы там естественно есть. Главное их отличие в том, что их размер не зависит от количества соединений. В то время как у синхронного варианта накладные расходы пропорциональны количеству соединений. Весь вопрос в том, в какой точке на графике эти две линии пересекаются. Лично я полностью уверен что эта точка находится правее "числа логических ядер". А вот насколько правее — это уже надо измерять...

_>>P.S. Кстати, с твоим мышлением тебе бы надо было держаться подальше от .Net, с учётом того, сколько там запускается всяческих сервисных потоков для каждого приложения. )))

S>И сколько же?

Я ответил в соседнем сообщение. Но в любом случае их больше, чем программист запускает для своих вычислительных целей. )
Re[26]: Зачем нам асинхронность?
От: Mystic Artifact  
Дата: 27.08.20 19:00
Оценка:
Здравствуйте, alex_public, Вы писали:

S>>4 (четыре) ядра.

_>Вообще то там 8 логических ядер. )
Я думаю ты и сам знаешь, что HT в серьез не рассматривается. Он конечно способен реально улучшить производительность, но это зависит от характера загрузки, при этом система будет интрузивно шедюлить на твое ядро то, чему там не место и простых воркэраундов этому нет.
Re[13]: Зачем нам асинхронность?
От: alex_public  
Дата: 27.08.20 19:41
Оценка:
Здравствуйте, vdimas, Вы писали:

_>>Нет, не может, потому как и в данной статье и в данной темке обсуждается не абстрактный асинхронный ввод-вывод в винде, а вполне конкретная реализация его из .net. И в ней для IOCP используется специальный пул потоков, который только этим и занимается.

V>Пул потоков занимается не только IO, ты можешь пихать в него произвольные свои задачи:
V>https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.queueuserworkitem?view=netcore-3.1#System_Threading_ThreadPool_QueueUserWorkItem__1_System_Action___0____0_System_Boolean_

Я правильно понимаю, что ты предлагаешь пихать пользовательские задачки в iocp пул .net? )))

_>>Так что в случае только одной операции ввода-вывода в каждый момент времени

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

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

А процитированное утверждение просто описывало первые точки этих графиков. )

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

V>Как это "синхронного с запуском отдельного потока"? ))
V>Как передавать данные в тот поток из потока GUI и как получать результат?

Передавать например с помощью замыкания ) А вот обратно действительно потребуется какой-то из вариантов взаимодействия потоков. Для GUI потока проще всего будет через сообщение (т.к. он и так сидит на их очереди).

_>>ну не считая выполнения кучи ненужного сервисного кода с очередями и т.п. в случае IOCP.

V>Считая. ))
V>В твоей самописной системе, состоящей из "основного" и "асинхронного" потока, все-равно придётся делать две очереди (если по-уму) — от основного потока в поток IO, и обратно.

Зачем в дочернем потоке нужна очередь, если он создан для выполнения ровно одной задачи? )

V>В дотнете подобные вещи автоматизированы через т.н. контекст исполнения. Например, в GUI потоке контекст требует отправлять продолжения задач обратно в этот же поток, поэтому, из IOCP-потока задача продолжена не будет, а будет своим обработчиком направлена в очередь GUI-потоку.


Правильно. Поэтому тут получается двойная очередь (в начале IOCP, а потом очередь сопрограмм GUI потока) — ухудшение латентности.

V>В общем, ты ничего на самописном синхронном IO не сэкономишь.


Ну экономия то там действительно смешная. Тем более, что для обсуждаемых задач (не серверных) все эти копейки вообще не принципиальны. Тут речь немного о другом. Асинхронный ввод-вывод (пускай и выпрямленный с помощью сопрограмм) — это в целом усложнение приложения, которое вполне обосновано преимуществом в производительности, который он даёт (но только для случая большого числа одновременных задач). Однако некоторые программисты предпочитают его использовать и для разовых операций, обосновывая это опять же большей эффективностью. Хотя на самом деле в таких сценариях эффективность на оборот меньше (пускай и на смешные копейки).
Re[26]: Зачем нам асинхронность?
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.08.20 01:50
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Вообще то там 8 логических ядер. )

_>А тут их 12. )))
Ну, то есть никаких "минимум 24" и не пахнет.
_>Лаптоп? фуфуфу — большая неудобная хреновина. Не сравнится по удобству работы с десктопом и по мобильности с планшетом. На конференции или встречи я обычно беру с собой планшетик.
А какой смысл брать с собой планшетик, на котором нет ничего из того, чем я занимаюсь? Планшетик (айпад про) у нас есть — отличная штука смотреть инстаграм и фильмы в самолёте.
Мобильность у моего T460 вполне отличная — 14", весит 1.7. Спину не оттянет.

_>Ну раз уж ты так в этом уверен, то тогда конечно же легко скажешь насколько 10000 лишних заблокированных потоков замедлит работу системы?

Сходу не скажу, надо замерять. Но даже просто запуск 10000 заблокированных потоков займёт заметное время

_>>>Да, и вообще говоря, чем более распараллелено твоё приложение, тем лучше. Потому как рост быстродействия современных процессоров в расчёте на одно ядро уже давно прекратился и увеличение производительности сейчас идёт только за счёт увеличения числа ядер.

_>Безусловно чрезмерное число одновременно работающих потоков ухудшает производительность. Но чрезмерное в данном случае — это тысячи, а не сотни и уж точно не десятки.
Вы как-то очень разбрасываетесь словами "вообще говоря" и "безусловно", при этом кидаетесь из крайности в крайность.
https://rsdn.org/article/baseserv/liveobj.xml
Автор(ы): Роман Хациев
Дата: 14.02.2002
Довольно давно я прочитал статью, автор которой объединил две концепции — многозадачность и объектно-ориентированное программирование. В результате получились так называемые "живые объекты". Идея крайне проста — при инициализации объекта создается отдельный поток и объект в нем живет своей жизнью, а создатель объекта по мере необходимости получает информацию о состоянии объекта из его свойств.

Есть ли у вас замеры на более современном железе?

S>>Как раз IOCP позволяет эффективно использовать ядра, без дополнительных накладных расходов.

_>Дополнительные накладные расходы там естественно есть. Главное их отличие в том, что их размер не зависит от количества соединений. В то время как у синхронного варианта накладные расходы пропорциональны количеству соединений.
Совершенно верно. O(N) vs O(1).
_>Весь вопрос в том, в какой точке на графике эти две линии пересекаются. Лично я полностью уверен что эта точка находится правее "числа логических ядер". А вот насколько правее — это уже надо измерять...
_>Я ответил в соседнем сообщение.
Это вот этот ответ имеется в виду?

А как же там всякие потоки для финализаторов, таймеров и т.п.? ) И да, я в таком ужасе как WPF не копался, но помнится мне один знакомый говорил, что у него там на пустом приложение (ну в смысле с какой-то базовой формочкой) автоматом 10 потоков стартует.

_>Но в любом случае их больше, чем программист запускает для своих вычислительных целей. )
Меня беспокоят не потоки сами по себе, а рост их количества. Запуск O(1) потоков для технических целей — это норм. Запуск O(N) потоков — уже плохо.
Ещё с девяностых годов известно, что кооперативная многозадачность эффективнее вытесняющей. Но в те времена технические средства по организации кооперативщины были крайне отсталыми; и в чистом виде она не очень хорошо работает с SMP.
Теперь же у нас есть прекрасные средства по организации fine-grained многозадачности, которые работают в комфортном для железке количестве потоков, и не требуют от программиста выворачиваться наизнанку.
А вы зачем-то предлагаете вернуться "назад в пампасы" и запускать ажно целый поток на каждый чих.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.