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)