• Pavel Emelyanov's avatar
    bfd: File-descriptors based buffered read · 53771adc
    Pavel Emelyanov authored
    This sounds strange, but we kinda need one. Here's the
    justification for that.
    
    We heavily open /proc/pid/foo files. To speed things up we
    do pid_dir = open("/proc/pid") then openat(pid_dir, foo).
    This really saves time on big trees, up to 10%.
    
    Sometimes we need line-by-line scan of these files, and for
    that we currently use the fdopen() call. It takes a file
    descriptor (obtained with openat from above) and wraps one
    into a FILE*.
    
    The problem with the latter is that fdopen _always_ mmap()s
    a buffer for reads and this buffer always (!) gets unmapped
    back on fclose(). This pair of mmap() + munmap() eats time
    on big trees, up to 10% in my experiments with p.haul tests.
    
    The situation is made even worse by the fact that each fgets
    on the file results in a new page allocated in the kernel
    (since the mapping is new). And also this fgets copies data,
    which is not big deal, but for e.g. smaps file this results
    in ~8K bytes being just copied around.
    
    Having said that, here's a small but fast way of reading a
    descriptor line-by-line using big buffer for reducing the
    amount of read()s.
    
    After all per-task fopen_proc()-s get reworked on this engine
    (next 4 patches) the results on p.haul test would be
    
            Syscall     Calls      Time (% of time)
    Now:
               mmap:      463  0.012033 (3.2%)
             munmap:      447  0.014473 (3.9%)
    Patched:
             munmap:       57  0.002106 (0.6%)
               mmap:       74  0.002286 (0.7%)
    
    The amount of read()s and open()s doesn't change since FILE*
    also uses page-sized buffer for reading.
    
    Also this eliminates some amount of lseek()s and fstat()s
    the fdopen() does every time to catch up with file position
    and to determine what sort of buffering it should use (for
    terminals it's \n-driven, for files it's not).
    Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
    53771adc
Makefile.crtools 1.62 KB