講義内容

基礎知識

HDD

Win一般


基礎知識篇

以下に説明する数式はこのような意味である.

log2 n
底2のlogである.nは任意の自然数ということにしておく.詳細はWikipediaでも確認して貰いたい.
a / b
まぁa÷bのことだ
a ^ b
「aのb乗」のこと.ブラウ座上でも無理をすれば「ab」で表示出来ないわけではないが,Accessibilityの観点から問題があり,キャレット(^のこと)を用いた.ただ,滅多に使わない漢字を多用したり,敢えて誤植を入れたりしている手前,視覚障碍者向けのブラウ座を使っている場合ソフト側に正確に理解されない可能性が多々あり,アクセシビリティなどと編輯者自身が宣えるかと云えば甚だ疑義が生じるのだが・・・

HDD篇

ファイルのプロパティをみると「サイズ」と「ディスク上のサイズ」という2つの数値がある.此の原因と背景を詳説する.
調べてみると
例えばWindowsのシェルであるexplorer.exeは1043968Byteと1044480Byteとある.画面のプロパティの実ファイルであるdesk.cplは124928Byteと126976Byteである.概して後者の方が僅かばかり大きいようである.時にはDirectX診断ツールdxdiag.exeのように1024000Byteで一致しているものも少なからず存在する.
どちらを調べるかで後々変わるが敢えて後者である「ディスク上のサイズ」をみてみる.
tutorial.vsd->61440
MDEN_D1.mdf->413339648
PW_DVD.iso->4999000064
・・・さっぱり分からない
実ファイルが事実上存在しないショートカットを調べてみる
ShiftJIS.lnk->4096
Opera.lnk->4096
他にもテキストエディタで"h"とだけ入力してファイル容量を調べても確認できる.
どうやら4096が怪しい.試しに割ってみると61440/4096=15・・・ぁれ割り切れた.次は126976/4096=31これもだ.おっきなファイルの方は?413339648/4096=100913.最後は4999000064/4096=1220459.全て割り切れてしまった.しかも15と31は互いに素なのでこれ以上同じ数で割る事はできないのは自明である.
では4096Byteとは一体何者か.この数字の意味を知る事が全ての事を解決できるはずだ.
その前に単位を整理しておく.ビット,バイト,オクテット,キロ,メガ,ギガなど様々な単位・接尾語が存在するのがPC用語の常だから.
容量に関して全ての基本はビットである.物の本によるとビットとは「一対の等確率事象のうちから一つの正しい選択をするのに必要な情報量」と定義される.広義には「n個の集合の等確率事象から一つの事象を正しい選択を可能にするために必要な情報のビット数はlog2 n」である.
一対は「1,0」,「真,偽」,「正,負」などの2値である.「正しい選択」というのは情報が2者で謬らないとする.
すると,「今日酒を呑んだ」事象が正しければ1を相手に送ればいい.そうすると受信者側は1を受け取る事で事象の同定をすることが出来る.故に2進数(binary)である.
ただ如何にも容量が少なすぎるのは目に見えているから幾つかを一括りにする.一番情報を必要とされるのは文字である.アルファベットを基本にしてきたからアルファベット26文字の大小文字,数字,記号,制御記号が一意に決まればいい.それはASCIIと呼ばれている.ASCIIはAmerican Standard Code for Information Interchangeの略である.
ところで何文字程度を実装できればいいかというと,アルファベット:26×2,数字:10,記号:26,制御記号:32+2の都合128「文字」である.既出の数式に投入するとn=128だからlog2 128=7.故に7ビットで全てが解決できる.この単位をバイトという.
けれども他のラテン文字日本語などに拡張すると確実に少ない.従ってもう1bit拡張して256「文字」にすることにした.n=256だからlog2 256=8.8ビットでも1byteと「表して」しまった.
これでは1byteと言えば7ビットでも8ビットでも良くなり障害が生じる.普段我々が用いるバイトは当然後者であるが,本質的には「対象となる情報系に依存する(Wikipedia)」事になる.此では非常に都合が悪いので常に8ビットを意味する単位が必要となりこれをオクテット(Octet)と称した.普段はバイトでも全然OKだが,特に通信関係などではよく使われる.
これでビットとバイト,オクテットの関係が分かった.次はキロ・メガ・ギガ・テラ・ペタなどである.以降当講義でバイトと表現する際は特に理のない限り8ビットを意味する.
バイトが小さい単位である事は分かった.次はキロバイトを定義する.コンピュータは2進数であるが我々の根幹は10進数(decimal)を用いている.用いる以上それほど大きな差異は好ましくない.2のm乗をキロと定義するとき,10の3乗に似た数が(・∀・)イイ.計算していくと2^2=4,2^3=8以下同様にして16,32,64,128,256,512,1024,2048,4096...やっぱり1024が一番近い.故に2^10=1024バイトを1キロバイトとする.
ところで問題の4096byteが漸く分かった.4096/1024=4キロバイト.結局全てのデータは4096byteを基本に管理されている.以降の議論は再び後に廻す.
次は当然メガである.機械的に振れば良く,2^10キロバイトを1メガバイトとすればいい.同様にして2^10メガバイトを1ギガバイト,2^10ギガバイトを1テラバイト,2^10テラバイトを1ペタバイトと定義する.
このように定義すると以下の問題が生じる.見かけ上計算しやすいのは10^3バイトを1キロバイトである.2^10バイト-10^3バイトを引けば24バイト分差異が生じる.オクテットのように違う単位を求めよう.2^10バイトを1キビ(kibi)バイトと定義するものである.以下特に明示するまでキロは10^3をキビは2^10を表現するものとする.
同様にメビバイト(MiB,2^20バイト),ギビバイト(GiB,2^30バイト),テビバイト(TiB,2^40バイト),ペビバイト(PiB,2^50バイト)を用いる.
しかし本質的には8ビット1オクテットを明示的に使わなければならないため例えば「キビオクテット」などと言うような表現が尤も好ましいと思われるが,流石にキビオクテットなる表記はされない.
「キビオクテット」を用いないとしたが,Wikipediaなどでは明示的に用いられているため,上記の文面は謬りに当たる.ところで今講義に於いては区別すべき点はキロとキビの差だけであり,オクテットとバイトの差異はない物と見做す.というのも,当講義でバイトと表現する際は特に理のない限り8ビットを意味するからである.以上追記した.
マーケティングの都合上従前の単位を用いる業界も少なからず存在する.その最たる例がHDDの容量である.都合が良いので手元にあるHDDを流用する.型番は「WDC WD2500JB-98GCA0」である.WD以降の数字三桁がギガバイト換算の容量である.即ち250GBということで販売されていた.
容量は言うまでもなく「238465」メビバイトである.メビバイトからキビバイトに置換するのは2^10を掛ければよいので明らかに244188160キビバイトである.再び2^10を掛ければ250048675840バイトとなる.桁区切りをすれば「250'048'675'840」バイトだから10^3で割って250048675キロバイト(小数点以下切り捨て,以下同様),250048メガバイト,250ギガバイトで確かに250ギガバイト存在する.
翻ってギビバイトで表現してみる.238465メビバイトだから2^10で割れば232ギビバイトである.即ちこのHDDはOS上からは見れば僅か232GiB(ギビバイト)としか表示されない.しかし買ったのは250GB(ギガバイト)のHDDであるから差分の18GB(ギビだろうかギガだろうか)が宙に浮いた格好となる.
注意して欲しい.この問題は何処から湧いてきたかというと2^10バイトを1キロバイトとした点に終始する.本来はギビバイトを用いるところをマーケティングの都合上ギガバイトとしている点である.パッケージには小さく「OSの表示により,容量が小さく表示されることがあります」とあるが本来は別の表現であろう.「OSの表示は232GiBと表示されますが問題ではありません」などと.
他のデータでも同様の事が言える.
これらの問題はPCについてよく知っている人については常識であったが最近初心者等にも外付けHDDなどの外部ストレージが普及してきた点が大きい.パッケージには250GBとあって買ったのに家に帰って接続して容量を見ると232GiBと表示されていれば誰だって目を疑う.それはキロでは双方の差は約2%だが,メガで約5%,ギガで約7%,テラで約10%と乗数が大きくなるにつれその差も大きくなる点があるからでもある.
しかしPC等ではGiBとGBを統一してGBとして表示している.本質的に分けているのはあるが,一般的ではなく雄座亜に解釈の余地を残しているのが実態である.
さて単位のお噺は此までだ.次こそ何故4キビバイトが全ての基礎になっているかを教鞭する.また「莫迦の壁」(養老孟司)にも似た壁が存在している事にも言及する.それには時間の針を少し戻す必要がある.


HDDには物理的な「場所」という概念が存在する.保存されている場所はXXXだからXXXにデータを取りに逝こうという事になる.シスアド・基本情報で勉強した通りそれには時間がかかる.即ち平均シーク時間,平均サーチ時間,データ転送時間の和である.
HDDは当然HardDiskDrive(硬い円盤)の略であるが中の構造は意外と知られていない.数枚のHardDiskがあってその間に磁気ヘッドが挟み込まれている.そして同心円状に有限の円を描いており,各々の円周を切ったところにデータが書き込まれる.
従って場所を特定するには3つの情報が必要となる.即ち面の場所,何トラック目か,そして何番目の扇形かである.それぞれシリンダ(C),ヘッダ(H),セクタ(S)と称する.
茲で問題になるのは平均サーチ時間の元である場所の同定である.従来(といっても極初期,15年かそれ以上前の話だが)はシリンダ,ヘッダ,セクタで決めていた.丁度3次元の位置を決めるのと似たような所である.従って1セクタ当たりに書き込める容量を既知とすれば,CHSさえ分かればそのHDDに書き込む事ができる最大容量が求まる.
1セクタ当たりの容量は特異なモノを除いて512バイトと決まっている.
今日尤も用いられている規格であるIDE(Integrated Drive Electronics)の場合,Cは2^16,Hは2^4,Sは2^8で都合2^(16+4+8)に分岐でき,理論上512×2^28バイト.である.単位を大きくしてみよう.1024×2^27バイトだから2^27キビバイト.ということは2^17メビバイトだから2^7ギビバイトで結局128ギビバイトまで表現する事が出来る・・・筈である.
しかしそううまくは逝かなかった.BIOSが対応していなかったためだ.BasicInput/OutputSystemの略であるBIOSは尤もメカニカルに近いソフトウェアである.これが対応していないと全ての機器は動かす事が出来ない.
でBIOS側ではC=2^10,H=2^8,S=6で都合2^(10+8+6)にしか分岐できない.即ち512×2^24バイト.同様にすると1024×2^23バイトだから2^23キビバイト,2^13メビバイト,2^3ギビバイトで8ギビバイトとなる.
なら8ギビバイトまで使えると思うと大間違いである.例えばBIOSで「H=128のデータを下さいな」とHDDに送ってHDDは対処出来るだろうか?明らかに無理である.即ちCHSで小さい方の値を使わないと駄目な事が分かる.結局C=2^10,H=2^4,S=2^6で都合512×2^(10+4+6)バイト.1024×2^19バイトで2^19キビバイト,2^9メビバイトで512メビが本当の限界である.
しかし此はHDD側とBIOS側の問題であり,両者で対応さえすれば解決する問題である.ところが此の儘ではHDD側のある128GiBの壁は厳然と存在する.
さてCHSではどうしても問題が生じてしまう.その端的な例は内周で4分割する長さと外周での長さが明らかに差異が原因で,冗長な容量が生じてしまう.そこで内周と外周でセクタを分けるのが単純な解決法であるが,セクタの定義が変質し場所を同定する事が出来ない.
結局CHS方式を諦めざるを得なくなり別の方式であるLBA(Logical Block Addressing)論理アドレス方式を用いている.これだと隣のアドレスは+1をすれば(・∀・)イイだけであり,CHS方式にあった「桁上がり」などの考慮は隠蔽されている.
LBA方式のビット数は28ビットであるから512×2^28バイトが限界である.この数値は当然CHS方式でのHDDとの互換性を持たしたモノである.
数年前に大問題になりWindowsXPの初期は128GiB以上でフォーマットすることが不可能であり,漸くSP1で解消された.これを「128GiBの壁」という.
解消の仕方は扱く単純でLBAのビット数を伸ばせば良いだけである.48ビットにしたのであり,理論上は128ペビバイト(2^27ギビバイト)という(今のところ)厖大な容量を持つ事が出来る.ただXPの仕様上2テビバイト(2^11ギビバイト)で止まるとされるがRAIDなどで簡単に2テビバイトを越える事が出来,どうにか動いているようである.
問題の4キビバイトは4096/512で8セクタ分となる.結局Windowsは8セクタを一纏まりとしてファイルを管理しているということになる.その単位はブロックと呼ばれる.
例えば8キビバイトの容量を持つファイルは特定の場所に4キビバイト分入れて(A)次の纏まりへのポインタを持たせ残りの4キビバイト分(B)を持つ.
adr XはデータXのあるLBA形式でのアドレスを示す物とする.
茲でadr A+1=adr Bであればヘッダを動かす必要は殆ど無いがadr A+2^10=adr B等となれば結構ヘッダを動かす事により無駄な時間が生じてしまう.これを「ファイルの断片化」という.フラグメンテーション(fragmentation)という奴だ.何故そうなるかはWikipediaに便利なものがあったから此を解説しよう.
凡例:□=空き領域,■・◆・★・●=ファイル
何もない何もない:□□□□□□□□□□□□□□□□□□□□
初期状態初期状態:■■■■■◆◆◆◆◆★★★★★□□□□□
ファイル◆を削除:■■■■■□□□□□★★★★★□□□□□
ファイル●を生成:■■■■■●●●●●★★★★★●●●□□
ファイル●の占めるサイズが■に続く空きに合わないため2つに分断された.
ということである.
adr ●5=10,adr ●6=16でありファイル●が断片化している.デフラグメンテーションを行うと
ステートメントの:■■■■■★★★★★●●●●●●●●□□
となる.こうすればadr ●5=15,adr ●6=16であり断片化が解消された.
この操作はHDDの性能を向上させるが不必要な書込が必須であるため,避けるユーザも少なくない.
次に殆ど容量のないテキストファイルでも4キビバイトと表示された理由を考えるがぢつは解答は既出である.
何の事はない「・・・8セクタを一纏まりとして」とあるように1バイトであっても8セクタを用いているのである.1セクタ目の冒頭を少しだけ使って残り4000バイトぐらいデータを持っていなくてもそれは無意味に消費される.
理論上HDDに入れられるファイル数は0バイトのファイル群を無視すれば容量を4キビバイトで割った数となる.当然最小は1である.


では1ブロックの容量を変えてみるとどうなるか考えてみる.
たとえばファイルの断片化を避けようと倍の16セクタ(8キビ)を一塊とすると,全然OK!のように見えるが無駄に使われている容量が増える.それは2つの理由からである.
1つは実使用量が10byteの時は,従来であれば4キビ-10byteで済んだがそれに輪を掛けて,4キビバイト分必要となる.
また12キビバイトであれば従来では3ブロックで済んだものの新方式では2塊の16キビ必要で茲でも4キビバイト分余る.
逆に4セクタ(2キビバイト)であれば今まで以上に断片化する可能性は明らかである.
以上の議論から「断片化の回避」と「不要容量の回避」は結局トレードオフの関係を持つ事がわかり,従前の通り4キビバイト・1ブロックが妥当かなと消極的に考えざるを得ない.
譬えば,この状況はWinR(ファイル名を指定して実行)でdfrg.mscから確認することが出来る.こうなっていればもう処置の方法はない.HDD上のデータを一旦別ストレージに移管して,でふらぐを掛けて,再び元に捩すしか方法はあるまい・・・このようなことにはならないように諸君も気をつけることである.


以上を纏めると

今回HDDに関してだが以下の情報は避けた.機会があれば講義する

Win®篇につづく