9

次の問題があります。

mmapwithを介して大量のメモリ (複数 GiB) を割り当てMAP_ANONYMOUSます。そのチャンクには、時々ゼロにする必要がある大きなハッシュ マップが保持されます。各ラウンドでマッピング全体が使用されるわけではないため (すべてのページに障害が発生するmemsetわけではありません)、時間がかかりすぎるため、お勧めできません。

これを迅速に行うための最良の戦略は何ですか?

意思

madvise(ptr, length, MADV_DONTNEED);

その後のアクセスで新しい空のページが提供されることを保証しますか?

Linux のman madviseページから:

この呼び出しは、アプリケーションのセマンティクスには影響しませんが ( MADV_DONTNEEDの場合を除く)、パフォーマンスに影響を与える可能性があります。カーネルはアドバイスを自由に無視できます。

...

MADV_DONTNEED

この範囲内のページへの後続のアクセスは成功しますが、基礎となるマップされたファイル (mmap(2) を参照) からメモリの内容を再ロードするか、基礎となるファイルのないマッピングのゼロ フィル オンデマンド ページのいずれかになります。

...

現在の Linux 実装 (2.4.0) では、このシステム コールをアドバイスというよりもコマンドと見なしています ...

それともmunmap、リージョンを新たに再マッピングする必要がありますか?

Linux で動作する必要があり、理想的には OS X でも同じ動作をします。

4

3 に答える 3

9

あなたの問題には、かなり移植性のあるはるかに簡単な解決策があります。

mmap(ptr, length, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);

MAP_FIXEDかなり恣意的な実装固有の理由で失敗することが許可されているため、返される場合は にフォールバックすることmemsetMAP_FAILEDお勧めします。

于 2013-09-03T16:18:37.510 に答える
1

このmadvise動作は確かに標準的ではないため、移植性はありません。

ゼロアウトしたい部分がたまたまマッピングの最後にある場合は、ftruncate. もう 1 ステップ導入する必要があります。

  1. shm_openデータに「永続的な」ファイル記述子を持たせる
  2. ftruncate必要なサイズに
  3. mmapそのFDの

その後、いつでもできます

  1. munmap
  2. ftruncate短いものに
  3. ftruncate必要な実際の長さに
  4. mmapまた

そして、「再マップ」した部分はゼロ初期化されます。

ただし、システムがページのゼロ化を行う必要があることにも注意してください。これは、コンパイラが生成するインラインのものよりも少し効率的かもしれませんが、memsetそれは確かではありません.

于 2013-09-03T16:01:34.600 に答える