Performance optimization in av::fixup - use buffered IO, not mapped file

Corinna Vinschen
Thu Dec 13 09:10:00 GMT 2012

On Dec 12 13:20, Daniel Colascione wrote:
> On 12/12/2012 12:09 PM, Ryan Johnson wrote:
> > I think I'm miscommunicating something here... let me try again.
> > 
> > Problem:
> > 
> > Attempts to execute a file with the NTFS "sparse" attribute force the Windows
> > loader to bypass the fs cache and fetch the file from disk.
> Almost. What actually happens is that the sparse attribute forces the system to
> flush the cache _for the whole file_ when av::fixup mmaps the binary, forcing
> the subsequent execution of the image we mmapped to reload everything from disk.
> Cygexec will work around the problem by avoiding the av::fixup mmap, but we
> shouldn't expect users to mount everything, including various build directories,
> cygexec. (I also haven't checked whether anything in /bin actually ends up
> sparse. It'd be interesting to see.)

cygexec is not such a good solution in the long run.  For 64 bit Cygwin
we *have* to know if the process to execute is a 32 or 64 bit process
so we can't quite avoid the hook_or_detect_cygwin test.

> We could also work around the problem by making av::fixup use regular buffered
> reads instead of mmap. Regular buffered reads don't seem to trigger the cache flush.

hook_or_detect_cygwin needs a second mapping if the file is big enough,
so rewriting this code to use ReadFile's isn't that simple.  The
question here is this.  Assuming we change MapViewOfFile to
VirtualAlloc/ReadFile, will that make things slower?  If so, it's not
worth it.  We would slow down the general case for the border case.

Of course we could use VA/RF only on sparse files since we know if an
executable is sparse, thanks to the FILE_ATTRIBUTE_SPARSE_FILE attribute.

> Still, I think that creating sparse files only on ftruncate is the right thing
> to do, at least for existing OS versions. Basically, almost nobody _uses_ sparse
> files in Windows (except us), so the paths that deal with them are optimized for
> simplicity and correctness, not performance.

It is kind of annoying that sparse files are something special in
Windows, rather then the normal case.

After a night's sleep I tend to agree with you, though.  I found an old
discussion in the cygwin archives from 2003 which also handled sparse
file slowness.  It seems this Windows code hasn't changed a lot since

Cygwin is used a lot for development, and it is famed for its slowness.
If we can notably speed up normal operation by disabling the automatic
sparse handling in lseek/write, I think we should do it.  For those
requiring sparseness on NTFS, we can add a "sparse" mount option and
run the code in lseek/write only if that mount flag is set.  And
for symmetry we should probbaly do the same in ftruncate.


Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

More information about the Cygwin-developers mailing list