在 Windows 上,它通常可以正常工作。我创建了一个测试应用程序(对不起,我讨厌 boost,因为我认为它的质量令人震惊,我的示例使用 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 文件时,我看到了您所描述的效果(我的进程的资源监视器内存数据:提交 25 MB,私有 20 MB,工作集和可共享 6.5 GB,这是我的数量空闲内存)。然而,互联网上的多个消息来源说这些数字没有任何意义并且不会影响性能,因为一旦任何进程请求更多内存,未使用的物理页面就会被丢弃,而且这个进程非常便宜(当然除非你正在写你的内存映射文件)。
或者,如果您对此行为真的不满意,您可以通过调用 VirtualUnlock 自己释放未使用的部分,如下所述:https ://stackoverflow.com/a/1882478/126995
或者,您只能映射您需要的文件部分。
但是您可以做的最好的事情是优化数据的布局。如果在您的数据文件中您将体素保留为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 是整数。