Click here to Skip to main content
11,577,710 members (45,888 online)
Click here to Skip to main content

Tagged as

Improve responsiveness in Windows with the FILE_FLAG_NO_BUFFERING wrapper

, 9 Mar 2010 Public Domain 26.9K 592 22
Rate this:
Please Sign up or sign in to vote.
Avoid swapping out valuable file system cache of other applications when accessing large files that you know are not accessed again later.

Introduction

When you read or write large files, valuable file system cache from other applications is being swapped out. This is not wanted if you know that your files are not going to be accessed again afterwards.

As a result, most people have experienced copying a large file where after all applications feel slow and unresponsive for a period of time until they have recached. Especially on servers that need low latency, this can be a really large problem.

Start a trend and use this wrapper to improve the all-over responsiveness of Windows Smile | :)

This Library

The only method to prevent swapping out cache is to open files with the FILE_FLAG_NO_BUFFERING flag. This, however, requires disk I/O requests to have sizes divisible by sector size (512 to 4096 bytes), which would require large rewrites of most applications that rely on being able to request different sizes.

This project contains a drop-in wrapper that offers the CreateFile_NB(), ReadFile_NB(), WriteFile_NB(), and CloseHandle_NB() functions that take care of queuing and adjusting the file size when closing a file opened for writing.

Note that the FILE_FLAG_WRITE_THROUGH and FILE_FLAG_SEQUENTIAL_SCAN flags would not solve the above mentioned problem; while data is committed immediately, a cached copy is still kept in memory.

Experiment

To illustrate the problem, start your Task Manager (the one at Ctrl + Alt + Del) and watch the Cached value in the Physical Memory area. Before our experiments, we need to invalidate as much cache as possible. Unfortunately, this is not easy on Windows. While the famous sfc /purgecache command commits all cache, it does not invalidate it. Do the following:

  1. Disable the ReadyBoost, SuperFetch, Readydrive, and SearchIndexer services. Especially SuperFetch is important because it fills up the cache at boot.
  2. Restart the computer. Simply logging off and on does not invalidate the cache and is not enough.

You should now see something like the image at the top of the article - the cache value is 14 MB, which is low and good.

Now, load the io.sln Visual Studio 2008 project. You will see the following lines in demo.c:

// #define NORMAL // Comment away this to make it use unbuffered disk I/O
_TCHAR large_file[] = _T("d:\\database.mdf");

Let large_file point to a file which is larger than your physical memory, leave the comment at the #define NORMAL flag as it is, and run the program. It reads the file into memory in chunks. Observe that the Cached value does not increase while running.

Now, uncomment the #define NORMAL flag and run it again. Observe that the Cached value increases. The same would happen if you had copied files on the command line or simply used the computer normally for a period of time.

Using the Code

Simply #include unbuf.h and unbuf.c in your project and append _UB to the function names of CreateFile(), ReadFile(), WriteFile(), and CloseHandle().

Do this for file accesses that have a significant amount of data and that you know are not accessed later by the user or by the application. This wrapper has certain limitations:

  • Files cannot be opened with both GENERIC_READ and GENERIC_WRITE at the same time.
  • The lpOverlapped parameter to CreateFile() is ignored.
  • Seeking (SetFilePointer()) is not yet supported.

Last but not least, it may not mimic the original functions perfectly in detail yet which could make it fail in certain applications. Please give it a good testing and let me know any compatibility issues or improvements that you may find. I will follow this forum closely the next weeks, to follow up.

History

  • 12-Jan-2010: First release.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

rlasse
QuickLZ
Denmark Denmark
QuickLZ - world's fastest data compression library (really), for C, C# and Java!

qpress - world's fastest file archiver (really), for Linux, Windows, MacOS, Solaris, etc. Way too fast for your storage system!

http://www.quicklz.com

You may also be interested in...

Comments and Discussions

 
QuestionSeek needed Pin
toddma6-Dec-12 4:32
membertoddma6-Dec-12 4:32 
I needed a seek. Here is what I added:
DWORD __cdecl SeekStart_NB(__in HANDLE hObject)
{
state *s = (state *)hObject;
return SetFilePointer(s->file_handle, 0, 0, FILE_BEGIN);
}
This great API fixes a messaging problem we had when saving files and doing user input into a dialog box simultaneously. (and with optimum speed)
QuestionWill this work in C++ in Visual Studio 10? (unicode) Pin
toddma9-Nov-12 6:18
membertoddma9-Nov-12 6:18 
Question[My vote of 1] Icky Code Pin
Member 799059123-Apr-12 13:00
memberMember 799059123-Apr-12 13:00 
GeneralSome remarks [modified] Pin
yarp9-Mar-10 20:41
memberyarp9-Mar-10 20:41 
GeneralOdd file sizes Pin
supercat99-Mar-10 10:22
membersupercat99-Mar-10 10:22 
GeneralRe: Odd file sizes Pin
yarp9-Mar-10 20:27
memberyarp9-Mar-10 20:27 
GeneralNew version Pin
rlasse9-Mar-10 9:48
memberrlasse9-Mar-10 9:48 
GeneralSystem memory leak Pin
Member 40209953-Mar-10 5:03
memberMember 40209953-Mar-10 5:03 
GeneralRe: System memory leak Pin
rlasse3-Mar-10 6:17
memberrlasse3-Mar-10 6:17 
GeneralQuestions Pin
hector santos23-Jan-10 1:38
memberhector santos23-Jan-10 1:38 
GeneralRe: Questions Pin
rlasse23-Jan-10 2:54
memberrlasse23-Jan-10 2:54 
GeneralRe: Questions Pin
hector santos23-Jan-10 4:28
memberhector santos23-Jan-10 4:28 
GeneralRe: Questions Pin
rlasse23-Jan-10 9:22
memberrlasse23-Jan-10 9:22 
GeneralRe: Questions Pin
hector santos25-Jan-10 14:21
memberhector santos25-Jan-10 14:21 
GeneralRe: Questions Pin
rprep12-Aug-11 9:52
memberrprep12-Aug-11 9:52 
GeneralBug [modified] Pin
rlasse13-Jan-10 10:33
memberrlasse13-Jan-10 10:33 
GeneralRe: Bug Pin
konikula18-Jan-10 21:56
memberkonikula18-Jan-10 21:56 
GeneralSparse files Pin
yafan12-Jan-10 4:24
memberyafan12-Jan-10 4:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150603.1 | Last Updated 9 Mar 2010
Article Copyright 2010 by rlasse
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid