[解決済み】mmap()とブロックの読み込みの比較
質問
私は、潜在的に100GB以上の大きさのファイルを処理するプログラムに取り組んでいます。ファイルは可変長レコードのセットを含んでいます。私は最初の実装を稼働させ、現在はパフォーマンスを向上させるために、特に入力ファイルが何度もスキャンされるため、より効率的にI/Oを行うことに注目しています。
を使用する際の経験則はありますか?
mmap()
と、C++のブロック読み込みの
fstream
ライブラリですか?私がやりたいのは、ディスクから大きなブロックをバッファに読み込んで、バッファから完全なレコードを処理し、さらに読み込むということです。
は、その
mmap()
のコードは、非常に面倒なことになる可能性があります。
mmap
のブロックはページサイズの境界線に置かれる必要があり(私の理解では)、レコードはページ境界を越えて置かれる可能性があります。このため
fstream
の場合、ページサイズの境界にあるブロックを読むことに制限されないので、レコードの先頭にシークして、再び読み始めることができるのです。
この2つのオプションは、実際に完全な実装を書き上げることなく、どのように決定すればよいのでしょうか?何か経験則(例.
mmap()
の方が2倍速い)、あるいは簡単なテストができますか?
どのように解決するのですか?
Linuxでのmmap/readのパフォーマンスについて最終的な情報を得ようとしていたところ、素敵な投稿に出会いました(
リンク
)のLinuxカーネルメーリングリストに掲載されました。 2000年のものなので、その後カーネルのIOや仮想メモリには多くの改良が加えられていますが、その理由がうまく説明されています。
mmap
または
read
の方が速いかもしれないし、遅いかもしれません。
-
への呼び出しは
mmap
よりもオーバーヘッドが大きくなります。read
(ちょうどepoll
よりもオーバーヘッドがあります。poll
よりも多くのオーバーヘッドを持つread
). 仮想メモリマッピングの変更は、異なるプロセス間の切り替えが高価であるのと同じ理由で、一部のプロセッサーでは非常に高価な操作となります。 - IOシステムはすでにディスクキャッシュを利用できるので、ファイルを読めば、どのような方法を使ってもキャッシュに当たるか外れるかです。
しかし
- 特にアクセスパターンがまばらで予測不可能な場合は、一般にメモリマップの方がランダムアクセスが速くなります。
-
メモリーマップでは、以下のことが可能です。
保つ
を使用することで、キャッシュからページを削除することができます。 つまり、あるファイルを長時間酷使した後、一度閉じてから再び開くと、ページがまだキャッシュされていることになります。 とは
read
の場合、ファイルは何年も前にキャッシュからフラッシュされた可能性があります。 これは、ファイルを使用してすぐに破棄した場合には適用されません。 (もし、あなたがmlock
ページをキャッシュに残すことは、ディスクキャッシュを出し抜こうとすることであり、このような愚かな行為はシステムのパフォーマンスにほとんど寄与しません)。 - ファイルを直接読み込むのは非常にシンプルで高速です。
mmap/readの議論から、他の2つの性能に関する議論を思い出しました。
-
一部のJavaプログラマは、ノンブロッキングI/OがしばしばブロッキングI/Oよりも遅いことを発見してショックを受けていました。
-
他のネットワークプログラマーの中には、以下のことを知り、ショックを受けた人もいます。
epoll
よりも遅いことが多い。poll
を管理することが分かっているのであれば、これは完全に理にかなっています。epoll
は、より多くのシステムコールを必要とします。
結論
メモリマップを使うのは、データにランダムにアクセスする場合、データを長時間保持する場合、他のプロセスと共有できることがわかっている場合などです(
MAP_SHARED
は、実際に共有されていない場合は、あまり面白くありません)。 順次アクセスする場合や、読み込んだ後にデータを破棄する場合は、普通にファイルを読み込んでください。 そして、どちらの方法でもプログラムが複雑にならないのであれば、次のようにします。
その
. 多くの場合、ベンチマークではなく、実際のアプリケーションをテストすることなく、どちらが速いかを示す確実な方法はないのです。
(ネクロで申し訳ないのですが、答えを探していたらこの質問がGoogleの結果のトップにずっと出てきてしまいました)
関連
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] Javaでプレーンテキストファイルを読み込む
-
[解決済み] バイナリファイルの読み込みと各バイトのループ処理
-
[解決済み] ファイル全体を読み込むと、ファイルハンドルが開いたままになりますか?
-
[解決済み] Pythonで大きなファイルを読み込むための遅延メソッド?
-
[解決済み】ファイルアクセスにmmapを使用するのはどんな場合ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された
-
[解決済み】ファイルアクセスにmmapを使用するのはどんな場合ですか?