2011-12-23 4 views
5

memcpy/memmoveは、ソースからデスティネーションへの複製(データのコピー)です。実際のバイト単位でソースデータをコピーせずに、ある仮想アドレスから別の仮想アドレスにページを移動するには何かが存在しますか?私には完全に可能なようですが、どのオペレーティングシステムでも実際にこれが可能ですか?ダイナミックアレイは広く普及している概念ですが、物理的にコピーすることで成長させることは、無駄な操作です。あなたはギガバイトで、配列のサイズについて話し始めるとき、それはちょうど例えば200ギガバイトの配列に100ギガバイトの配列を成長想像(拡張できません。それは今< $ 10Kの範囲内のサーバー上で完全に可能だ問題だ。OSは物理的にコピーせずにあるアドレスから別のアドレスに移動することを許可していますか?

void* very_large_buffer = VirtualAlloc(NULL, 2GB, MEM_COMMIT); 
// Populate very_large_buffer, run out of space. 
// Allocate buffer twice as large, but don't actually allocate 
// physical memory, just reserve the address space. 
void* even_bigger_buffer = VirtualAlloc(NULL, 4GB, MEM_RESERVE); 
// Remap the physical memory from very_large_buffer to even_bigger_buffer without copying 
// (i.e. don't copy 2GB of data, just copy the mapping of virtual pages to physical pages) 
// Does any OS provide support for an operation like this?  
MoveMemory(very_large_buffer, even_bigger_buffer, 2GB) 
// Now very_large_buffer no longer has any physical memory pages associated with it 
VirtualFree(very_large_buffer) 

答えて

6

の異なるビューをマッピングすることにより、プロセス間のメモリをコピーするには、Linux上でmremapであることを行うことができます。

プレーを呼び出すことゼロコピーの再割り当てを行うプロセスのページテーブルcan。すべての場合で可能ではありません(アドレス空間の断片化、および単に他の既存のマッピングの存在が問題です)。

manページ実際に、これは言う:

mremap()は仮想アドレスとメモリ・ページのマッピングを変更します。これは、非常に効率的なrealloc(3)を実装するために使用できます。

+0

これはまさに私が探しているようです。私はこれをlinuxと他の場所の標準的なダムのメモリコピーで使うことができます。 – Eloff

+1

またはreallocと同様の方法をボンネットの下で使用することを希望します。 :) – onitake

2

はい、それはメモリの一般的な用途は、「移動」にファイルをマッピングされたのですか、ある程度まではファイル

0

つまり、次の100GBにはアクティブなメモリがないことを絶対に保証できないため、連続して使用できないことがあります。

一方、配列が互いに隣り合っていなくても(または同じサイズであっても)、不揃いの配列(配列の配列)を使用することができます。ダイナミックアレイの利点の多くは、100GBの領域に拡張できない場合があります。

+1

私の理解は、実際の物理RAMページが連続している必要はない、それは仮想アドレッシングのポイントです。しかし、断片化していない仮想アドレス空間は200GB必要です(現行のオペレーティングシステムでは現在64ビットプロセスに8TBのアドレス空間があるので、これは問題ではありません)。 – Eloff

1

すべてのPOSIXシステムでこれが可能です。 mmapをファイルディスクリプタ(openまたはshm_open)で使用し、匿名ではない場合は、マップを解除してから、切り捨て(縮小または拡大)してから再度マップします。同じページに対して異なる仮想アドレスを取得することがあります。

+0

私が間違っていれば修正しますが、マッピング解除するとすべて汚いページをそのファイルに戻す(遅延していますか?)したがって、ページを再マップすると、ページにアクセスすると、潜在的にそれらをファイルから読み込む必要があります。そこには多くの実装の詳細がありますが、ディスクIOを引き起こすことによるメモリコピーの回避は勝利する可能性は低いです。私は興味がありますが、mmapはしばしばプロセス間でメモリを共有するために使用されるので、最初のマッピングを閉じずにファイルを拡張したり、同じファイルの2番目のマッピングを作成したりできませんか?それは私が考えるゼロ移動コピーになります。 – Eloff

+0

まず、 'shm_open'を使うとファイルがないので、何も書き込めません。そして、「開かれた」場合でも、マップ解除がページを書き戻すとは思っていません。ファイル記述子を閉じるだけで強制的に実行されます。 –

+0

shm_openのケースでは、マップしていないという理由だけでコンテンツを失うことはないと思います。そしてあなたは正しいと思います。ダーティなページは、マッピングを閉じただけで書かれないでしょう。システムの書き込みバッファに残っているはずです。 – Eloff

関連する問題