サブフォルダへの書き込みは親フォルダへの書き込みよりも高速です

サブフォルダへの書き込みは親フォルダへの書き込みよりも高速です

dd を使用して書き込みパフォーマンスを計測したところ、奇妙なことに気付きました。/data/emzed2 への書き込みは /data への書き込みよりも高速です。パフォーマンスを計測した方法は次のとおりです。

$ dd if=/dev/zeroof=/data/emzed2/テストファイルbs=32

^C4921834+0 レコード

4921834+0 レコード出力 157498688 バイト (157 MB) コピー済み、2,87329 秒、54.8 MB/秒

$ dd if=/dev/zeroof=/データ/テストファイルbs=32

^C2487991+0件のレコード

2487991+0 レコード出力 79615712 バイト (80 MB) コピー、2,6501 秒、30.0 MB/秒

両方のフォルダーは SSD ドライブの同じパーティションにあります。私は Ubuntu 14.04 を使用しており、実験を数回繰り返しましたが、結果は同様でした。

何が起こっているのか分かりますか?

答え1

ext4の最適化の影響を受けているようですこれらのいくつかは、Ext4 ディスクレイアウトドキュメンテーション。

dd などを使用してファイルを拡大するたびに、新しいデータ用に何らかの場所が割り当てられます。最終的に、ファイルは断片化される可能性があります。つまり、データがディスク全体に複数のチャンクに分散される可能性があります。断片化は、読み取りおよび書き込み時に速度低下の原因としてよく知られているため、ファイル システムの実装では、多くの場合、これを回避しようとします。断片化は、SSD よりも回転ディスクで (ヘッドが連続するチャンクに移動する必要があるため) はるかにコストがかかりますが、ほとんどのファイル システムの実装では、SSD で回転ディスクに最適化された戦略を使用しています。

上記のドキュメントに記載されている3番目、4番目、5番目の「トリック」の組み合わせかもしれないあなたのケースではサブディレクトリへの書き込みの方が速い理由を説明してください。

5 番目のトリックは、ディスク ボリュームが 128 MB のブロック グループに分割されることです。 […] ルート ディレクトリにディレクトリが作成されると、inode アロケータはブロック グループをスキャンし、そのディレクトリを、見つかった中で最も負荷の少ないブロック グループに配置します。

その結果、emzed2おそらく 128MB の空きブロックが作成されたと考えられます。

4 番目のトリックは、可能な場合は、ディレクトリ内のすべての inode をディレクトリと同じブロック グループに配置することです。

その結果、/data/testfileは (おそらく負荷が高い) ルート ブロック グループに作成され、 は(おそらく空の)ブロック グループ/data/emzed2/testfileに作成されます。emzed2

3 番目のトリックは、ファイルのデータ ブロックをその inode と同じブロック グループに保持しようとすることです。

の場合/data/emzed2/testfile、ファイル システムは最初にブロック グループ内のすべてのデータ ブロックを割り当てますemzed2。このブロックが最初は空だった場合、最初の 128 MB では断片化はまったく発生しません。 の場合/data/testfile、ファイル システムは最初にルート ブロック グループがまだいっぱいになっていない場合はそれを埋め、次にデータを格納する他の場所を探します。

また、ファイルは一度に 32 バイトずつ大きくなります。幸い、ext4 などのファイル システムは、要求した量よりも多くのデータ (ext4 の場合は 8kb のチャンク単位) を割り当て、割り当てを遅らせようとします。 でも同様なパターンが見られる可能性がありますがbs=8196、ブロック サイズが大きいほど速度の差は小さくなる可能性があります。

関連情報