Very slow throughput writing to disk

Hello, experts.

I’m a filesystem developer new to Windows. I’ve written a
homegrown metadata cache for my fs. It basically seems to work but
I find that on Windows, when I flush my metadata cache to my log file,
the performance is terrible. I flushed to my log when I got
to ~1MB of dirty metadata. The buffers in my homegrown
cache are 512 bytes each. So I’m flushing about 2000 of
them. The flush takes about 15 seconds or a throughput
of about 70kb/second. Here is my flush algorithm:

For each dirty 512-byte buffer
KeInitializeEvent( &event);
irp = IoBuildAsynchronousFsdRequest( IRP_MJ_WRITE,
deviceObject,
(void *)Buffer,
Length,
&Offset,
NULL );
IoSetCompletionRoutine( irp,…);
IoCallDriver(irp);

This kicks them all off asynchronously, as I understand it.
Then I wait for all the I/O’s to complete. I try to be smart by
waiting on the last one I started:

while (not done)
KeWaitForSingleObject(event)

My I/O completion routine marks my metadata buffers as
being “done” so I only wait for those that are still pending.

As I said, this does seem to work. But the performance is
so bad, I feel like I’m missing a basic Windows concept.
This algorithm works well on other platforms.

Any help would be greatly appreciated!

Tim,

  1. Make your buffers 4k each and that will probably give you 8x
    performance.

  2. Better yet, make them 64k and that will probably give you 128x
    performance.

Jerry.

xxxxx@lists.osr.com wrote on 03/13/2006 02:45:30 PM:

Hello, experts.

I’m a filesystem developer new to Windows. I’ve written a
homegrown metadata cache for my fs. It basically seems to work but
I find that on Windows, when I flush my metadata cache to my log file,
the performance is terrible. I flushed to my log when I got
to ~1MB of dirty metadata. The buffers in my homegrown
cache are 512 bytes each. So I’m flushing about 2000 of
them. The flush takes about 15 seconds or a throughput
of about 70kb/second. Here is my flush algorithm:

For each dirty 512-byte buffer
KeInitializeEvent( &event);
irp = IoBuildAsynchronousFsdRequest( IRP_MJ_WRITE,
deviceObject,
(void *)Buffer,
Length,
&Offset,
NULL );
IoSetCompletionRoutine( irp,…);
IoCallDriver(irp);

This kicks them all off asynchronously, as I understand it.
Then I wait for all the I/O’s to complete. I try to be smart by
waiting on the last one I started:

while (not done)
KeWaitForSingleObject(event)

My I/O completion routine marks my metadata buffers as
being “done” so I only wait for those that are still pending.

As I said, this does seem to work. But the performance is
so bad, I feel like I’m missing a basic Windows concept.
This algorithm works well on other platforms.

Any help would be greatly appreciated!


Questions? First check the IFS FAQ at https://www.osronline.
com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@attotech.com
To unsubscribe send a blank email to xxxxx@lists.osr.com