質問

ハードドライブのシークがどのように機能するかを理解しようとする人を助けてください

小さなバイナリデータベースファイルがあり、読み取りパフォーマンスは絶対に不可欠です。ファイル内の数バイトをスキップする必要がある場合は、seek()またはread()を使用して不要なデータを破棄する方が高速です。

ハードドライブの平均シーク時間が10msで、読み取り速度が300MB / sの場合、3MBより小さい値のseek()よりread()の方が速いと計算しました。本当ですか?新しいシークを実行するときに、既存のストリームの読み取りにはないオーバーヘッドがありますか?

インデックスに適したファイル構造はどれだと思いますか。

Entry1:Value:PointerIntoToData
Entry2:Value:PointerIntoToData
Entry3:Value:PointerIntoToData
Data, Data, Data

Or

Entry1:Value:Data
Entry2:Value:Data
Entry3:Value:Data

値が正しくない場合、エントリを読み取るときに無視されます。そのため、ファイルをストリーミングするときは、次のことが速くなります。 1.エントリが不要な場合は、seek()を使用してスキップします 2.エントリが不要な場合、それを読み取ってからデータを破棄します 3.または、エントリが必要な場合は最初の構造を使用します。最後にデータリポジトリへのseek()。

エントリは4バイト、値は8バイト&データは12KBです

乾杯

役に立ちましたか?

解決

すべての seek システムコールは、次の読み取りが行われるファイル内の位置を変更することです。ドライブヘッドは移動しません。データの読み取りまたは書き込みが行われるとドライブヘッドが移動し、OSが次に何をするかを直接制御することはできません。

必要のない大量のデータを読み取ると、すべての読み取りデータにOSバッファーのスペースが必要になり、古いデータが破棄されるため、影響があります。そのため、大きなファイルでシークを使用すると、ファイルシステムのキャッシュが少なくなります。


以下に記載するすべての内容は、データベース全体をメモリに収めることができないことを前提としています。可能であれば、それをしてください。すべてを読んで、ファイルの最後に新しいデータと変更されたデータを追加してみてください。無駄なスペースを気にせず、たまに圧縮するだけです。


データベースが大きすぎる場合:

データは、ブロック(またはページ)単位で物理ドライブに読み書きされます。同様に、OSのディスクIOの基本単位はページです。 OSがディスクからデータをキャッシュする場合、ページ全体にもあります。したがって、seekまたはreadを使用して数バイト先に進む必要があるかどうかを考えることはほとんど意味がありません。高速にしたい場合は、ディスクIOが実際にどのように機能するかを考慮する必要があります。

まず、nobugzで既に言及されている、参照の局所性。各操作で使用するデータがファイル内で互いに近くにある場合、OSはより少ないページを読み書きする必要があります。一方、データを拡散すると、一度に多くのページを一度に読み書きする必要があり、常に遅くなります。

インデックスのデータ構造について。通常、これらは Bツリーとして編成されます。これは、ページ化された読み取りと書き込みでメモリに保存された大量のデータを効果的に検索するために特に作られたデータ構造です。

そして、データを整理するための両方の戦略が実際に使用されています。たとえば、MS SQL Serverはデフォルトで最初の方法でデータを保存します。データは個別に保存され、インデックスにはファイル内のインデックス付き列とデータ行の物理アドレスからのデータのみが含まれます。ただし、クラスター化インデックスを定義すると、すべてのデータがこのインデックス内に保存されます。他のすべてのインデックスは、物理アドレスではなくクラスター化インデックスキーを介してデータを指します。最初の方法は簡単ですが、クラスター化インデックスに基づいてデータの範囲を頻繁にスキャンする場合は、もう1つの方法がはるかに効果的です。

他のヒント

「絶対に不可欠」な方法シークアクセスですか?最適でないソリューションを使用してアプリケーションをテストしましたか?そのテスト中に、本当のボトルネックがどこにあるかを判断するためにベンチマークを行いましたか?そうでない場合は、結果に驚くでしょう。

次に、さまざまな方法を試して、実行時間を比較します。さまざまなシステム負荷でテストします(つまり、アプリケーションを除いてシステムがアイドル状態のとき、およびビジー状態のとき)。

新しい高速のハードドライブにさまざまな内部最適化があり、作業が不要になると、現在のハードドライブに基づく最適化が不正確になる可能性があることを考慮してください。

シーケンシャル読み取りは、ヘッドシークを必要とするものよりも常に高速です(位置シークではありません)。シーケンシャルリードの一般的なハードドライブパフォーマンスは50〜60 MB /秒で、最悪の場合〜0.4 MB /秒まで低下します。ドライブヘッドを配置すると、基本的にシリンダー内のデータを無料で取得できます。ファイルシステムのキャッシュは、シリンダーからセクターを先読みすることでそれを利用します。

ただし、ディスクシリンダー上のデータの配置を制御することはできません。ドライブのジオメトリも推測できません。ボリュームが断片化されると、スループットは時間の経過とともに著しく悪化する可能性があることに注意してください。メモリにデータをキャッシュして、パフォーマンスを探す必要があります。その時点で、参照の局所性について心配します。

ファイルを常にメモリにマップし、ポインターなどを介してアクセスできます。これにより、通常、アクセスがより簡単に 高速になります。

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