どうすれば読み取り先のバイトを取得できますか?
-
02-10-2019 - |
質問
プログラムは将来近くの情報を必要とする可能性が高いため、プログラムが実際に要求するよりもディスクから読み取られます。私のアプリケーションでは、ディスクからアイテムを取得するとき、要素に関する情報の間隔を表示したいと思います。私が要求して表示する情報の量とスピードの間には、トレードオフがあります。ただし、OSは私が要求したものよりも多く読み取っているため、すでにメモリ内にあるこれらのバイトにアクセスすることは無料です。 OSキャッシュの内容を見つけるためにどのAPIを使用できますか?
または、メモリマップされたファイルを使用できます。その場合、問題はページがディスクに交換されているかどうかを調べることになります。これは一般的なOSで実行できますか?
編集:関連論文 http://www.azulsystems.com/events/mspc_2008/2008_mspc.pdf
解決
少なくともLinuxでは、実際に2番目の方法を使用できます。 mmap()
ファイル、次に使用します mincore()
どのページが常駐しているかを決定する機能。 Manページから:
int mincore(void *addr, size_t length, unsigned char *vec);
mincore()
呼び出しプロセスの仮想メモリのページがCore(RAM)に居住しているかどうかを示すベクトルを返します。カーネルは、アドレスから始まるページに関するレジデンシー情報を返しますaddr
、そして継続しますlength
バイト。
もちろんここには人種的な状態があります - mincore()
ページは常駐していると言うことができますが、アクセスする直前に交換される可能性があります。 c'est la vie.
他のヒント
あなたは間違った推定から始めています。少なくともLinuxでは、OSはプログラムのアクセスパターンを把握しようとします。ファイルを順番に読み取ると、カーネルは順番にプリフェットします。ファイルをたくさんジャンプすると、カーネルはおそらく最初は混乱しますが、プリフェッチを停止します。
あなたが実際に それは ファイルに順番にアクセスすると、おそらくプリフェッチされているものがわかります:次のデータブロック。あなたがランダムに求めている場合、おそらく近くで他に何もプレッチされていません。
これに別の方法でアプローチしてみてください。 read()を呼び出す前に、情報を取得する 必要, 、 電話 fadvise() OSにあなたが何を知らせるために 欲しいです 読み込みを開始するために..
また、たまたまファイルキャッシュにあるデータでのみ動作することで正しく実行できるアプリケーションの種類を知りたいと思います。もう少し情報を投稿した場合、あなたのニーズに対処する良い方法を見つけることができると思います。
確かにWindowsで行うことはできません。 Windowsでは、読み取りの動作はOS次第であり、たとえそれがどれだけ先に読んだかを教えてくれたとしても、あなたが見つけたとすぐに、メモリページがあるので、それはあなたに何の役にも立たないでしょうキャッシュに使用されると、他の使用のために回収された可能性があります。
同じことは、ページが居住者であるかどうかを判断するためにもたらされます。他のスレッドが他の何かのメモリを必要とする場合、答えが変わる可能性があることがわかりました。
Windowsで薄いことをしたい場合は、バッファリングをオフにして自分でバッファーを管理できます。これは最速のIOパスですが、最も複雑なパスでもあります。非常に注意する必要があり、多くの場合、OSはそれをより良くすることができます。
OSキャッシュの内容を見つけるためにどのAPIを使用できますか?
POSIXシステムに対してこれを行う標準的な方法は確かにありません。Linuxに固有の非標準的な方法を知りません。確かに知ることができる唯一のことは、ファイルシステムがページサイズの倍数(通常は4kb)で読み取られていることです。したがって、読み取りが小さい場合、周囲のページのデータがメモリにあることを高い確率で(確かではありませんが)知ることができます。
読み取りシステムを完了するのにどれだけ時間がかかったかをタイミングするようなトリッキーなことをすることができます。それが高速であれば、それは数百秒以下であるため、おそらくキャッシュのヒットでした。 1ミリ秒ほどになると、おそらくキャッシュミスでした。もちろん、これは実際にはあまり役に立たず、非常に壊れやすいです。
ファイルシステムがデータをユーザーバッファーにコピーしたら、データをディスクから保持しているバッファーをすぐに廃棄できることに注意してください。それはおそらくこれをすぐにはしませんが、あなたは確かに言うことはできません。
最後に、私は @Karmastanの提案を2番目にします。あなたが達成しようとしているより広い目的を説明してください。おそらくそれを行う方法がありますが、あなたが提案したものはそうではありません。