2

この問題のために、ファイルからプログラムに大きな 3 次元ボリュームをロードしていますが、通常は一度に 3 つの平面 (x、y、z) を見るだけで済みます。現在、Boost::Interprocess::File_Mapping を使用してファイル (32 GB) のマップを作成し、それを 24 GB の RAM を持つシステムにロードしています。現在の方法では、ファイルに単一の Boost::Interprocess::Mapped_Region を使用します。メモリ使用量はすぐに 99% に近づきます。

私はメモリ マップド ファイル I/O の世界に不慣れで、ファイルをセグメント化してメモリ使用量を削減する最善の方法を知りたいと思っています。サイズを縮小した領域 (たとえば、各 Z 平面) を作成すると、結果が改善されますか? 悪影響を与えずに、メモリの使用をできるだけ少なくしたいと考えています。

私はこれを正しい方法で行っていますか、またはこれを実行するためのより簡単な方法はありますか?

4

1 に答える 1

1

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 は整数) であることを確認してください。

于 2013-02-16T16:55:57.537 に答える