粒度ってなんですか(続き)

先日はクエリに対してのキャッシュを例に挙げたので分かり辛かったので、反省。
もっと身近なところから例をとりましょう。
皆さん、ファイルをメディアに保存しますけど、その格納単位ってご存知ですか?

例えば、15KByteのファイルを作成したとします。これは1KByte=1024Byteなので
メディア(ディスク)上では15360Byteの領域を占有しているのか、というとさにあらず。
設定などにもよりますが一般的には16KByteの領域を使用します。
ファイルサイズを少し小さくしてみましょう。13KByteではどうでしょうか。
やはり16KByteを占有します。
では、もっと小さくして1Byteのファイルでは?
一般には4KByteのサイズを占有します。

つまり、ファイルシステム的には4KByte単位(4KByteの倍数)でファイルシステムを占有します。
なぜこんなことになっているのかというと、ある程度の決まった大きさの固まりで扱った方が
何かと都合がいいからなんですね。
引っ越しの時に何でもかんでも段ボールに箱詰めするのに似ています。
メディア上では512Byteを最小単位としているものがほとんどですが、これでは細かすぎるので
いくつかを束ねてもう少しサイズを大きくして使用しています。
4Kbyteは512Byteのちょうど8倍で、いうまでもなく8は2の階乗なので、切りがいいというわけです。

これがファイルシステムにおける粒度の例です。

また、OSが管理するメモリも同様にこの単位を持ち、その単位は一般的に4KByteです。
これは偶然の一致ではなく、メモリ<=>メディア(ディスク)のやり取りにおいて無駄を省くために
このようなサイズの一致が計られています。

ただし、特定用途、例えば、小さいファイル(例えば512Byte以下)を大量に扱うことが分かって
おり、全体としての使用可能メモリが限られている場合などはこの粒度を細かくした方が効率が
いいのはいうまでもありません。

全体が10MByteの領域で4Kbyteの粒度を使用した場合では2560個のブロックしか作成できませんが、
512Byteの粒度では20480個のブロックを作成できます
(実際にはこれらブロックとファイルそのもののマッピングテーブル(いわゆるFATとかi-node)
が必要なので、使用できる領域はさらに少なくなる)

実装によっては64/128/256/512/1024/2048/4096といった複数の粒度を持ち、これらを複数
組み合わせることにより、より効率的なブロックの割り振りを可能にするものもあります。
メモリであれば、アクセスが桁違いに速いためにこういう工夫をする余地はあるでしょう。
同様のアプローチをディスクで行う場合にはもっとサイズを大きくする必要があるでしょう。
これはメモリが高速で、単価が高い。ディスクはその逆というメディアの特性を生かした
割り振りです。
かように粒度という概念は重要なのです

最近市民権を得つつあるSSDはディスクよりはランダムアクセスが高速(と引き換えに上書き
が遅い)ですので、この辺りのアプローチも変わってきてしかるべきです。
最近だとBtrfsでしょうかね。(SSDに特化してるわけではないが、現在のファイルシステム
はハードディスクに特化して発展して来たため、SSDで現在のファイルシステムを使用した
場合、本来の性能を出し切れない部分がある)

と、ここまで書いてきたのはいいんだけど、もっとマシな解説を見つけた。orz
(私が書いた内容を100%カバーしているわけではないのが救いだ)

ブロック (データ) - Wikipedia

ps
この辺の話の派生としてフラグメンテーションの話も出てくるのだけど、これはDBMSでは
非常に重要な話。
一昔前はフラットファイルを一気に作成するアプローチがあったようだけど、最近は
オンデマンドでファイルを拡張していくのが主流のような。
ディスクも安いことだし、フラットファイルの方が効果を享受できる気はするのだけど。
まぁ、SSDの場合はそのありがたみはあまり受けないんだろうけど。

最近いじったDBMSではmongodbはフラットファイルのアプローチに見える。
(正確には、フラットファイルに傾倒したアプローチというべきか。現実には多かれ
少なかれ、フラットファイルを使いますね。デフォルトサイズの違いだけという側面も
あるにはある)