2016-06-25 18 views
2

ext4ファイルシステムで1TB SSD(500MB /秒で読み書き)に大きなファイルがあるとします。このファイルは1TBに近いサイズです。ファイルの途中でfseek()の速度を見積もる方法。数秒か数ミリ秒かかりますか?ありがとう。ファイルシステムのシーク速度を見積もる方法

+1

SSDにはテープ巻き戻しがありません(テープリーダーの場合 - 分)、テープスイッチがない場合(テープライブラリの場合 - 分)、ヘッドは移動せず、ディスクの1回転を待ちます(HDD - 5/7/10/15ミリ秒= 0.010秒)。だから、SSDでは、シリコン・コントローラだけが変換ルックアップを行い、NANDチップからの実際の読み出し(安価なTLCでは遅く、エラー・チェック/正しい) - 数十億マイクロ秒(0.000010秒)かかるでしょう。 SATA/SCSI/Linuxのブロックサブシステムをエミュレートする際のオーバーヘッドがブロック/ VFSスタックを介してデータを渡す。どんなポジションにでもシークできるのは、latency.Test with fioです。 – osgx

+0

情報のために@osgxありがとうございます。私は高速アクセス速度を認識しています。しかし、ここには多くのブロックが含まれています。ファイルの先頭から場所にジャンプするときに、必要なジャンプがたくさんあるかどうか、それぞれのジャンプに10usecかかる場合は100000回のジャンプに時間がかかることがあります。ファイルシステムがseek()を実装する方法を理解していないと思います – packetie

+0

これはファイルシステムに固有ですが、一般的な方法があります。私の最初のコメントでは、ハードウェアがソフトウェアからの1つの要求に対して時間を求めていました。ファイルを検索するようFSに依頼するとき、ファイルブロックのIDを見つける必要があります。 UnixのFSファイルには、inode https://en.wikipedia.org/wiki/Inodeがあり、inodeにはブロックのリストがあります。ファイルの最初の短い部分はinode(直接ブロック)で直接記述され、次に次の部分のブロックのリスト(間接)でブロックするリンクがあり、次にリストを持つブロックへのリンクで二重間接的にリンクする - https:/ /en.wikipedia.org/wiki/Inode_pointer_structure – osgx

答えて

5

fseekのレイテンシを推定するには、ソフトウェア作業とハードウェアシーク時間の2つの部分に分けてください。ソフトウェア作業は、ハードウェアブロックストレージデバイスへのいくつかの "ランダム"要求(I/O操作)を生成するext4ファイルシステム(FS、LinuxではこれはカーネルのVFSサブシステム)の実装です。ハードウェアは、それぞれのランダム要求を処理するのにある程度の時間を費やします。

古典的なUNIXファイルシステム(UFS/FFS)とそれ以降に設計されたlinuxファイルシステムは、スーパーブロックを使用してディスク上にファイルを記述し、ファイルをinode(既知の場所にiノードの配列があります)固定サイズのブロック(Linuxでは最大4KB)。 OSのファイル名からinodeを探すには、スーパーブロックを読み込み、パス内のすべてのディレクトリを見つけ、ディレクトリからデータを読み込んで、ファイルのinode番号を調べる必要があります(ls -iは現在のディレクトリのinodeを表示します)。次に、スーパーブロックOSからのデータを使用して、iノードが格納されている場所を計算し、iノードを読み取ることができます。

iノードはチェックし、通常はツリー状の構造では、ファイル・データ・ブロックのリストが含まれていhttps://en.wikipedia.org/wiki/Inode_pointer_structurehttp://e2fsprogs.sourceforge.net/ext2intro.html ext2 inode pointer structure, gpl from e2fsprogs.sourceforge.net/ext2intro.html

ファイルの

最初の部分、KBの数十は、(iノードに直接、直接記載されている、ブロックに格納されていますブロック; ext2/3/4で12)。より大きなファイルの場合、inodeは、ファイルブロックのリスト(間接的にアドレス指定されたブロック)を持つ1つのブロックへのポインタを持ちます。ファイルが大きければ、inodeの次のポインタが使用され、 "間接的な二重ブロック"が記述されます。これは、他のブロックを列挙するブロックを指し、それぞれに実際のデータを持つブロックへのポインタを含みます。時には三重間接ブロックポインターが必要になることがあります。これらのツリーはかなり効率的です。あらゆるレベルで〜512(4KBブロック、ポインタあたり8バイト)の程度があります。したがって、ファイルの途中からデータにアクセスするには、ext2/3/4が最大4〜5の低レベルのI/O要求を生成する可能性があります(スーパーブロックはRAMにキャッシュされ、iノードもキャッシュされます)。これらの要求はアドレスの結果ではないため、ブロックデバイスに対してほぼランダムにシークします。

現代のLinux FS(ext4、XFS)の亜種は、エクステント(https://en.wikipedia.org/wiki/Extent_(file_systems))と呼ばれる膨大なファイルストレージを最適化しています。エクステントを使用すると、FSがブロックリストではなく、ファイルフラグメント/ポインタペアの配列(start_block、number_of_consequent_blocks)としてファイルの配置を記述できるようになります。すべてのフラグメントはおそらくMBの一部から最大128 MBです。 4つの最初のエクステントはinode内に格納され、さらに多くのエクステントはツリー状の構造として再び格納されます。したがって、エクステントでは、ファイルの中央にアクセスするために2〜4回のランダムI/O操作が必要になる場合があります。

HDDは、円形のトラックを正確に修正するためにヘッダーを物理的に移動する必要があり(トラックの正確に位置ヘッダーを移動する必要があるため、1/8または1/16のような回転の一部が必要です) )、ディスク(プラッター)を1回転(回転)まで待ってトラックの一部を取得します。 HDDの典型的な回転速度は、5400と7200 rpm(revolutions per minute,90 rpsと120 rps)または高速エンタープライズHDD - 10000 rpmと15000 rpm(160 rpsと250 rps)です。したがって、ディスクのランダムな位置からデータを取得するために必要な平均時間は、約0.7-1回転であり、典型的な7200 rpm hdd(120rps)では約1/120秒= 8ms(ミリ秒)= 0.008sです。あなたの状況には最大で4~5回のランダムなリクエストがありますので、HDDの場合は、の40 msの近くにファイルがあると予想されることがあります。 (最初のシークはもっとコストがかかるでしょう、次のシークは、ブロックポインタツリーの一部がOSによってキャッシュされるので安くなるかもしれません;次のブロックは、最初のシークが要求された直後に読むことができるので、

SSDには回転部品や可動部品がなく、SSDのリクエストも同様に処理されます。 SSDコントローラは、要求されたブロックIDを自身の変換テーブルを使用して内部nandチップ+ブロックIDに解決し、次に実データを読み込みます。 NANDからのデータの読み出しはエラー訂正コードをチェックし、ブロックを正しく読み取るためにはいくつかの内部再読書が必要になることがあります。より安価なNAND型の読み込みが遅くなります - TLCはすべてのセルに格納された3ビットのデータで8レベルです。 MLCで高速 - 4レベルのデータ2ビット。存在しないSLC SSDでは1ビットとわずか2レベルの非常に高速です。また、磨耗したSSDや、ファームウェアにエラーがあるSSD(セル充電の劣化モデルが間違っている)では、読み込み速度が遅くなります。

SSDでのこのようなランダムアクセスの速度は非常に高く、通常50000〜100000 IOPS(I/O operations per second、通常は4KB)のようなSSD仕様であると宣言されています。高いIOPS数はより深いキューのために宣言されるかもしれないので、SSD(QD1)の実際の平均ランダム読み出し待ち時間は、要求ごとに200-300 microseconds(0.2〜0.3ミリ秒; 2014年;待ち時間の一部は遅いSATA/SCSIエミュレーションです; NVMe SSDはより単純なソフトウェアスタックを使用する方が高速になります)。私たちの4-5リクエストでは、SSDのfseek を数ミリ秒と見積もることができます。例えば、 1 - 1.5 msまで、時にはそれ以上の時間があります。

fseekに必要な時間を確認するには、strace -T ./your_fseek_programを使用します。すべてのシステムコールを実行するのに必要な時間を報告します。しかし、実際のレイテンシを得るには、シーク時間だけでなく、次のreadシステムコールの時刻もチェックする必要があります。このテストを実行する前に、ルートからecho 3 > /proc/sys/vm/drop_cachesコマンド(https://unix.stackexchange.com/questions/17936/setting-proc-sys-vm-drop-caches-to-clear-cache)でカーネルキャッシュをフラッシュすることができます。

iozone、iometer、fioなどのI/Oベンチマークを試して、シークレイテンシを見積もることもできます。

+0

ありがとうございました!私は100回投票することができます。 – packetie

+0

codingFun、SSDについて:SSDは1リクエストレイテンシが高い(200〜300マイクロ秒)一方、SSDは多くのリクエストを並行して処理することができます(深いキュー、MLC /エンタープライズ/ NVMeデバイスの方が深い、 HDDのキューサイズは非常に限られています。 https://gist.github.com/jboner/2841832 - 「各プログラマーが知るべき待ち時間の数値」(2012!)を1 MB順次読み取りの一部でチェックしてください。 – osgx

+0

リンクのおかげで、非常に便利です!大きなファイルにシーク時間を追加することもできます:-) – packetie

関連する問題