質問

私は現在、交換選択とk-wayマージを使用して外部マージソートを含むプロジェクトに取り組んでいます。 C ++ [Linuxで実行]でプロジェクトを実装しました。その非常にシンプルで、現在は固定サイズのレコードのみを扱っています。

読み書きには(I/O)FSTREAMクラスを使用しています。数回の反復でプログラムを実行した後、私はそれに気づきました

  • i/o 4K以上のサイズの要求のためにブロックを読み取ります(一般的なブロックサイズ)。バッファサイズを4Kを超えると、パフォーマンスが低下します。
  • 出力操作はバッファリングを必要としないようで、Linuxはバッファリング出力に対応しているようです。したがって、Writeの特別なバッファーを維持し、Write(Record [])を使用してすぐにそれらを洗い流す代わりに、書き込み(レコード)を発行します。

しかし、アプリケーションのパフォーマンスは大きくないようです。パフォーマンスを改善するにはどうすればよいですか?読み取りブロックの世話をするために特別なI/Oスレッドを維持する必要がありますか、それともこの抽象化を提供している既存のC ++クラスがありますか?(JavaのBufferedInputStreamのようなもの)

役に立ちましたか?

解決

このような高性能I/Oは、最も簡単に行われます mmap. 。これにより、カーネルにI/Oを実行し、アプリのCPU時間をスケジュールする自由がはるかに自由になります。たとえば、ifstreamを使用して1 MBで読み取ると、すべてのデータが読み取られた場合にのみカーネルが戻ることができます。ただし、MMAP()を使用すると、データは利用可能になると徐々に返すことができます。

ただし、それがどのように起こるかを理解する必要があります。データがRAMにあるように見えるからといって、ランダムにアクセスできるように扱う必要があるわけではありません。餌を与えないでください std::sort. 。これにより、MMAP'ed領域のランダムな部分に触れ、ページの障害が右と中央に左になります。その結果、ランダムなページの障害を解決しようとする重いディスクが発生します。その代わり、 mmap() 2つの入力とそれらをマージします。 MMAPコマンドはカーネルに将来必要なデータを伝えたため、カーネルはできるだけ速くデータをフィードし、マージソートは一時的にデータが外れているときにページ障害(すなわちストール)をページにします。

他のヒント

C低レベルIOライブラリの使用を見てください。http://www.linuxtopia.org/online_books/programming_books/gnu_libc_guide/low_002dlevel-i_002fo.htmlまたftp://ftp2.developpez.be/developps/linux/alp/alp-apb-low-level-io.pdf

ずっと前のWindowsでは、Fopenを使用するよりも低レベルのIOオープンを使用して10倍速く実行するIOをいくつか獲得しました。

たぶん、あなたは同じパフォーマンスのメリットを得ることができないでしょう、私はそれが何かになることを知っています。

ストリームは、Plain-C I/Oと比較して、パフォーマンスの問題で知られています。実際、それらは「使いやすく、さまざまな状況に適している」として機能しますが、パフォーマンスの欠如です。私があなたの状況でやることは、CスタイルのI/Oに切り替えて、プロファイリング、プロファイリングの結果に基づいて行動することです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top