stdio performance in tango, stdlib, and perl

James Dennett jdennett at acm.org
Sat Mar 24 19:50:36 PDT 2007


Andrei Alexandrescu (See Website For Email) wrote:
> James Dennett wrote:
>> Walter Bright wrote:
>>> James Dennett wrote:
>>>> Andrei Alexandrescu (See Website For Email) wrote:
>>>>> cout << a << b;
>>>>>
>>>>> can't guarantee that a and b will be adjacent in the output. In
>>>>> contrast,
>>>>>
>>>>> printf(format, a, b);
>>>>>
>>>>> does give that guarantee. Moreover, that guarantee is not between
>>>>> separate threads in the same process, it's between whole processes!
>>>>> Guess which of the two is usable :o).
>>>> As you appear to be saying that printf has to flush every
>>>> time it's used, I'd guess that it's unusable for performance
>>>> reasons alone.
>>> In order for printf to work right it does not need to flush every time
>>> (you're right in that would lead to terrible performance). The usual
>>> thing that printf does is only do a flush if isatty() comes back with
>>> true. In fact, flushing the output at the end of each printf would not
>>> mitigate multithreading problems at all. In order for printf to be
>>> thread safe, all that's necessary is for it to acquire/release the C
>>> stream lock (C's implementation of stdio has a lock associated with each
>>> stream).
>>
>> That would be true, except that Andrei wrote that
>> the guarantee applied to separate processes, and
>> that can only be guaranteed if you both use some
>> kind of synchronization between the processes *and*
>> flush the stream.
>>
>> Andrei's claim went beyond mere thread-safety, and
>> that was what I responded to.
> 
> Lines don't have to appear at exact times, they only must not
> interleave. So printf does not have to flush often. I've used
> printf-level atomicity for a long time on various systems and it works
> perfectly.

With sufficiently short lines, where the value of
"sufficiently" depends on which platform and which
kind of file descriptor you're writing to.  printf
is likely to end up calling write with no locking;
write isn't atomic past a certain (or uncertain)
size, and has no reason to make the boundary
coincide with the end of a line.

> Is a system-dependent assumption? I don't know. It sure is there and is
> very helpful on all systems I used it with.

Can you name one specific system where this is
documented as working reliably, or where it can
be shown to do so?  I've *seen* interleaving
between processes, and lived with it in debugging
code for performance reasons, but for reliable
output have used other mechanisms.  I understood
this to be a widely known problem with printf,
write et al.

-- James



More information about the Digitalmars-d mailing list