フラグ FILE_FLAG_IO_BUFFERING を使用して、バッファリングなし (ファイル キャッシュをスキップ) で一連のファイルを読み取ると、通常の読み取り (このフラグを使用しない) よりも高速になります。それが高速である理由は、「バッファリングなし」メカニズムがシステム ファイル キャッシュをスキップし、アプリケーションのバッファに直接読み込まれるためです。
アプリケーションはコールド環境で実行され (ディスクの最適化後、マシンの再起動後)、システム ファイル キャッシュは実行前に関係するファイルと共にキャッシュされません。
これは、これらの API とフラグに関する msdn ドキュメントからのものです。
ただし、まったく異なるパフォーマンス動作が発生します。FILE_FLAG_IO_BUFFERING フラグを使用してファイル ハンドルが作成された後、一連のファイルを次々に同期的に読み取ります。ファイルのセットを読み取るのにかかる時間は 29 秒です。このフラグを使用せずに正常に読み取った場合 (ファイル キャッシュに関連ファイルが保持されていない場合のアプリケーションのコールド ラン時)、所要時間は約 24 秒です。
詳細:
総ファイル数: 1939
総ファイル サイズ (すべての合計): 57 MB
FLAG_IO_NO_BUFFERING あり: 29 秒 (読み取りにかかる時間)
FLAG_IO_NO_BUFFERING なし: 24 秒 (読み取りにかかる時間)
読み取りを実装するコードは次のとおりです。
DWORD ReadFiles(std::vector<std::string> &filePathNameVectorRef)
{
long totalBytesRead = 0;
for(all file in filePathNameVectorRef)
totalBytesRead += Read_Synchronous(file);
return totalBytesRead;
}
DWORD Read_Synchronous(const char * filePathName)
{
DWORD accessMode = GENERIC_READ;
DWORD shareMode = 0;
DWORD createDisposition = OPEN_EXISTING;
DWORD flags = FILE_FLAG_NO_BUFFERING;
HANDLE handle = INVALID_HANDLE_VALUE;
DWORD fileSize;
DWORD bytesRead = 0;
DWORD bytesToRead = 0;
LARGE_INTEGER li;
char * buffer;
BOOL success = false;
handle = CreateFile(filePathName, accessMode, shareMode, NULL, createDisposition, flags, NULL);
if(handle == INVALID_HANDLE_VALUE)
return 0;
GetFileSizeEx(handle, &li);
fileSize = (DWORD)li.QuadPart;
bytesToRead = (fileSize/g_bytesPerPhysicalSector)*g_bytesPerPhysicalSector;
buffer = static_cast<char *>(VirtualAlloc(0, bytesToRead, MEM_COMMIT, PAGE_READWRITE));
if(buffer == NULL)
goto RETURN;
success = ReadFile(handle, buffer, bytesToRead, &bytesRead, NULL);
if(!success){
fprintf(stdout, "\n Error occured: %d", GetLastError());
return 0;
}
free(buffer);
RETURN:
CloseHandle(handle);
return bytesRead;
}
FILE_FLAG_NO_BUFFERING を使用しない場合よりもこのコードの実行速度が遅いと思われる理由について、ご意見をお聞かせください。ありがとう。