3

アイデアは比較的単純ですが、実装にはいくつかの複雑さが見られるため、今でも可能かどうか疑問に思っています.

  • 私がやりたいことの例は、バッファにデータを生成し、このバッファの内容をファイルマップすることです。メモリ空間にファイルの内容を仮想的に格納する代わりに、元のバッファの内容をシステム キャッシュに転送し (これはゼロ コピー操作である必要があります)、すぐにダーティにします (これにより、ファイルがフラッシュされます)。データは最終的にディスクに出力されます)。

もちろん、私が言及した複雑な点は、バッファーの割り当てを解除してマップを解除する必要があることです (データは現在システムキャッシュの責任下にあるため)、その方法もわかりません。

重要な側面は次のとおりです。

  • プログラムは、ファイルがリンクされて作成されるタイミングを制御できます。
  • プログラムは、ファイルのサイズを予測する必要はなく、データセットが大きくなったときにファイルを再マップする必要もありません。代わりに、最終的にファイルにマッピングする前に、(データセットがこれ以上大きくならないことが確実にわかっている) 満たされるまで、初期バッファーを再割り当てできます (これには効率的なメモリ アロケーターを使用します)。
  • データは、ファイルにマップされた後でも同じ仮想メモリ アドレスを介してアクセス可能であり、メモリ内コピーは 1 つもありません。

1 つの仮定は次のとおりです。

  • mmap/mremap が管理するメモリ空間に対して、mmap/mremap よりも効率的に動的バッファを管理できる任意のメモリ アロケータ (または一般的なメモリ管理スキーム) を使用できます。常に遅くなります。

では、(1) これらの要件は制約が多すぎますか? (2) この仮定は正しいですか?

PS: この質問のタグは任意に選択する必要がありましたが、BSD と Windows がこれをどのように行うかについても興味があります。もちろん、POSIX API で既にこれが可能であれば、それは素晴らしいことです。

更新: バッファーを、プライマリ メモリに割り当てられたプライベート メモリ (通常の VMM を使用する任意の OS のプロセス/タスクに対してプライベート) のスペースと呼びます。高レベルの目標には、別の入力 (私の場合はネットワーク) を使用して任意のサイズのデータ​​セットを生成し、それが生成されたら、(ネットワークとプロセス自体に) 長期間アクセスできるようにして保存することが含まれます。プロセスでディスクに。

  • データセットをプライベート メモリに保持し、通常どおり書き出すと、OS がスペースを必要とするときにスワップされるだけです。これは、データセットが既にディスク上にあるため、少しばかげています。
  • 別のリージョンをマップする場合、バッファの内容をそのリージョン (システム キャッシュに存在する) にコピーする必要があります。

私が見る別の方法は、(a) ページが無駄にスワップアウトされないようにするため、および (b) プロセスが保持するメモリが多すぎないようにするために、本格的なユーザーランド キャッシュの読み取りと書き込みをディスク自体に書き込むか使用することです。それ自体は、とにかく最適に実行することは不可能であり (カーネルにその仕事を任せたほうがよい)、単に下りる価値があると私が考える道ではありません (利益を得るには複雑すぎる)。

更新: Nominal Animal の回答を考慮すると、要件 2 と 3 は問題ではありません。もちろん、これは仮定が正しくないことを意味します。彼が証明したとおりです (オーバーヘッドは最小限です)。要件 1 も緩和しましたO_TMPFILEが、まさにこれに最適です。

更新: LWN に関する最近の記事では、中間のどこかで次のように言及されています。 . これは、実際 (2014 年 4 月現在) 少なくとも Linux (およびおそらく他のオペレーティング システム) でこれを行う方法がなく、ましてや標準 API で行う方法がないことを示唆しています。この記事は PostgreSQL に関するものですが、記事で定義されていないこの質問の特定の要件を除いて、問題は同じです。

4

1 に答える 1