Windows では、通常は問題なく動作します。私はテスト アプリケーションを作成しました (残念ながら、その品質が魅力的だと思うのでブーストは嫌いです。私のサンプルでは代わりに ATL を使用していますが、基になる Windows API は同じです):
HRESULT TestMain( LPCTSTR strFileName )
{
CAtlFile file;
HRESULT hr = file.Create( strFileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING );
if( FAILED( hr ) )
return hr;
CAtlFileMapping<BYTE> mapping;
hr = mapping.MapFile( file );
if( FAILED( hr ) )
return hr;
size_t sz = mapping.GetMappingSize();
BYTE res = 0;
for( size_t i = 0; i < sz; i++ )
res ^= mapping[ i ];
printf( "Read the complete file, %Iu bytes, the XOR is %.2X\n", sz, int( res ) );
return S_OK;
}
8GB RAMを搭載したマシンで12GBファイルを読み取るように求められたとき、あなたが説明している効果を見ました(私のプロセスのリソースモニターメモリデータ:コミット25MB、プライベート20MB、ワーキングセット、共有可能な6.5GB。空き RAM)。ただし、インターネット上の複数のソースは、これらの数値は何の意味もなく、パフォーマンスにも影響しないと述べています。これは、プロセスがより多くのメモリを要求するとすぐに未使用の物理ページが破棄され、このプロセスは非常に安価であるためです (もちろん、あなたのメモリマップファイル)。
または、この動作に本当に不満がある場合は、https ://stackoverflow.com/a/1882478/126995 で説明されているように、VirtualUnlock を呼び出して、未使用の部分を自分で解放できます。
または、ファイルの必要な部分だけをマップすることもできます。
しかし、それについてできる最善のことは、データのレイアウトを最適化することです。データ ファイルでボクセルを として保持している場合は、代わりdouble voxels[x][y][z]
に として保存しますstruct { double voxels[8][8][8] } blocks[x/8][y/8][z/8]
。このように、ブロックサイズはページサイズである正確に 4kb であり、たとえば XZ プレーンにアクセスするだけでよい場合は、桁違いに多くの I/O 帯域幅を節約できます。つまり、データの前にヘッダーがある場合は、ヘッダーのサイズが 4kb*n (n は整数) であることを確認してください。