Re: fprintf && write
- From
- Lev Walkin ()
- To
- Andrey Melnikov ()
- Date
- 2003-06-05T00:49:18Z
- Area
- RU.UNIX.PROG
From: Lev Walkin <vlm@netli.com>
Andrey Melnikov wrote:
> AM>> Выкидываю все эти fprintf() и заменяю на свою функцию:
>
> AM>> static char wr_buf[1024];
>
> BR> Для теста - прокатит, а вообще стоит избегать глобальных переменных. Я
> BR> нахожу что весь код нужно писать реентерабельным. Если нет ОСОБЫХ причин
> BR> делать иначе :) Я бы этот буфер увеличил раза в 4 и засунул внутрь функции
> BR> :)
> Дороже выйдет. Войти в процедуру, отрезать кусок стека. Выйти - подчистить.
> Код у меня не реентрабельный - задача того не требует.
Что это за бред? Процедура отрезания куска стека НЕ занимает
дополнительного времени. Процедура подчистки стека НЕ занимает
дополнительного времени. Мало того, из-за того, что стек постоянно
используется, он будет в кеше процессора, а значит и программы с данными
на стеке будут выполняться в среднем быстрее. Не тогда, когда ты их
крутишь в цикле for(), чтобы проверить быстродействие, а тогда,
когда этот кусок кода используется в реальных (больших) программах.
Тогда возникнет интересный момент: скопище "быстрых" участков кода
становится программой, которая работает медленнее, чем аналогичная,
у которой соответствующие кусочки значительно медленнее.
> BR> 2. Кроме write у тебя есть только один вызов API - select (в Виндах я бы
> BR> сказал "Вызов функции ядра", но думаю что и тут с select этот термин будет
> BR> точен). Морал - тормозит (сверх ожидаемого) он.
> Наверное - слово тормозит здесь не самое уместное. Я бы сказал - чаще
> делиться временем со всеми остальными задачами. Или я неправ ?
Скорее, тратится время в ядре на проверку аргументов и исполнения
алгоритма системного вызова.
> BR> Моя теория такова (еще раз шаркну ножкой что я не юниксоид, но основные
> BR> принципы едины):
>
> BR> * Твой код делает два системных вызова.
> Да. Но без них - у меня два варианта:
>
> 1. Получить засыпание при вызове fprintf(...) где-то в ядре на write(..) на
> очень большое время, что увы неприемлимо.
> 2. Использовать alarm(time), write()/fprintf(), alarm(0); - я получу 3
> системных вызова.
а попробуй так:
1. при открытии дескриптора переводи его в non-blocking mode.
2. В подобных твоему участках кода делай _сначала_ write(), а уж потом,
если write() вернул -1/EAGAIN, то select:
while() {
if(write()) {
select();
...
}
}
Тогда имеется вероятность, что за один вызов write() управишься в
большом количестве случаев.
--
Lev Walkin
vlm@netli.com
--- ifmail v.2.15dev5
* Origin: Netli, Inc. (2:5020/400)