Re: fprintf && write
- From
- Igor Sysoev ()
- To
- Boris Rudakov ()
- Date
- 2003-06-07T16:19:50Z
- Area
- CARBON.COPY
* Forwarded from area 'RU.UNIX.PROG'
From: Igor Sysoev <is@rambler-co.ru>
Boris Rudakov <Boris.Rudakov@p4.f9.n5054.z2.fidonet.org> wrote:
> >> 3. Как можно ждать нескольких РАЗНОРОДНЫХ СОБЫТИЙ ???? Сколько я ни
> >> читал про юникс API я как-то не нашел ничего, равного по мощи и
> >> универсильности виндозному WaitForMultipleObjects. В данном примере
> >> я упихал туда ивент
>
> IS> Насчёт универсальности соглашусь, а вот мощности я не наблюдаю - 64
> IS> объекта на поток - это не мощность, а игрушки. Причём увеличить
> IS> MAXIMUM_WAIT_OBJECTS нельзя из-за бинарной совместимости. Ну и, кроме
> IS> того, даже если было бы можно, то уже на тысячах объектах он бы сильно
> IS> тормозил.
>
> Хех, это очень неоднозначный вопрос :)
>
> Казалось бы ограничение - плохо, unlimited - хорошо, но в данном случае есть
> одно серьезное соображение, вполне оправдывающее ограничение в 64 хэндла.
>
> Чего ты ждешь в WaitForMultipleObjects (или любом юниксоидном аналоге) ? Когда
> один из объектов будет просигнален и тебе будет пора предпринимать некие
> управляющие приседания. Любые приседания, даже очень быстрые, требуют
> вычислительных затрат. Узнал ты что что-то прокачалось - начал готовить новые
> буфера, делать еще море разнообразных действий, потом запускаешь следующую
> итерацию IO, потом готовишь блок данных для нового ожидания и только потом
> приступаешь к следующему циклу ожидания. Все это - время. Чем больше
> одновременных асинхронных операций - тем это время больше. А квант нити -
> ограничен и весьма мал. Нужно несколько нитей.
Я не вижу причин, почему следующий квант опять не достанется этому
же процессу, если нет готовых к исполнению более приоритетных процессов.
> Получается интересный вывод: нет никакого смысла в рамках одной нити ожидать
> очень большого количества событий - оверхед на служебные вычисления может
> превысить "порог разума". И, как я уже заметил выше, приложение для работы с
> большой загрузкой должно иметь несколько нитей.
С точки зрения производительности (а не удобства программирования),
я считаю, что число работающих трэдов в процессе должно быть равно
числу процессоров. То есть, на однопроцессорной машине должен быть
ровно один трэд. Тут есть, правда, одно "но" - я сказал "работающих".
Дело в том, что, несмотря на то, что в NT многие операции могут быть
ассинхронными, тем не менее, существует ряд операций, которые синхронны,
по крайней мере, с точки зрения API, например, открытие файла - CreareFile().
В при вызове синхронного потенциально долгоиграющего сисколла процесс
потеряет свой квант или даже кванты. В такой ситуации дополнительные трэды,
конечно, не помешают, но они должны уйти спать дальше как можно быстрее,
когда процесс работает, не блокируясь в ядре. Майкрософт это понял
достаточно давно и сделал в NT 3.5 I/O completion ports.
>Даже на однопроцовой системе несколько нитей позволяют тебе лучше
>конкурировать с другими процессами, т.к. шедаллер оперирует нитями.
Для конкуренции с другими процессами существуют приоритеты, а не число нитей.
> Итого, я считаю что ограничение WaitForMultipleObjects в 64 хэндла - совершенно
> оправдано. В большинстве случаев их больше 5-и не бывает :)
Случаи, они разные бывают. Например, мой любимый пример про десять
тысяч сокетов. В NT его правильнее обрабатывать через iocp одним или
несколькими (если позволяют процессоры) трэдами. При использовании
WaitForMultipleObjects() понадобиться минимум 150 трэдов, которые
система будут всё время переключать.
> Однажды я писал озверевший конвейер IO для одного нашего сервера, расчитаный на
> очень существенную нагрузку. Там я спроектировал пул нитей с автобалансировкой
> загрузки и как-раз воспользовался ограничением в 64 хендла: 2 хендла всегда
> были ивентами, отвечающими за управление нитями пула (будили их когда нужно
> было перестраивать структуру распределения каналов ввода/вывода), а < 62
> хендлов могло быть либо хендлами файлов (как сокетов, так и пайпов), либо
> ивентами, либо хендлами spooled-процессов. Так вот, загружать нити рабочего
> пула контролем бОльшего числа параллельных операций было бы бессмысленно - они
> бы тратили слишком много времени на служебные вычисления в рамках своих квантов
> времени. Ежу понятно что совокупное время служебных вычислений хоть и зависит
> от числа нитей, но крайне мало, но вот рассредоточить его по большому
> количеству нитей - очень целесообразно. Каждая нить реагирует на необходимость
> предпринимать управляющие действия гораздо оперативнее. Я думаю что соотношение
> нитей рабочего пула к числу параллельных асинхронных операций как 1:62 - вполне
> удачно :)
А почему для это не воспользоваться I/O completion ports ?
Они и балансировали.
У меня, кстати, есть пару мыслей об aio, но в ответ на твой предыдущий вопрос
они не укладываются, поэтому я их постить не стал. Могу запостить вне трэда.
--
Игорь Сысоев
http://sysoev.ru
--- ifmail v.2.15dev5
* Origin: Rambler Office news site (2:5020/400)