実際にデータをコピーせずに、ある仮想アドレス範囲から別の仮想アドレス範囲にページをコピーする方法が必要です。範囲は非常に大きく、レイテンシーは重要です。mremap はこれを行うことができますが、問題は古いマッピングも削除することです。マルチスレッド環境でこれを行う必要があるため、古いマッピングを同時に使用できるようにする必要があります。他のスレッドがそれを使用できないと確信したら、後で解放します。カーネルを変更せずに、ハックですが、これは可能ですか? このソリューションは、最近の Linux カーネルでのみ動作する必要があります。
3 に答える
はい、できます。
mremap(old_address, old_size, new_size, flags)
サイズが「old_size」の古いマッピングのみを削除します。したがって、「old_size」として 0 を渡すと、何もマップ解除されません。
注意: これは共有マッピングでのみ期待どおりに機能するため、そのような mremap() は以前に MAP_SHARED でマップされた領域で使用する必要があります。つまり、ファイルに基づくマッピングは必要なく、mmap() フラグに "MAP_SHARED | MAP_ANONYMOUS" の組み合わせをうまく使用できます。一部の非常に古い OS は「MAP_SHARED | MAP_ANONYMOUS」をサポートしていない場合がありますが、Linux では安全です。
MAP_PRIVATE 領域でこれを試すと、結果は memcpy() とほぼ同じになります。つまり、メモリ エイリアスは作成されません。しかし、それでも CoW 機構を使用します。あなたの最初の質問からは、エイリアスが必要なのか、それとも CoW のコピーでもよいのかが明確ではありません。
更新: これを機能させるには、明らかに MREMAP_MAYMOVE フラグも指定する必要があります。