Windows 3.1の特徴は,セグメント方式のメモリ管理とノンプリエンプティブなマルチタスクである。いずれも,Windows 95が登場したときに「Windows 95より劣っている」とされた技術である。しかし,技術の優劣を付ける場合は,その背景も考える必要がある。今回は,特にメモリ管理方式について考えてみたい。

 セグメントとは,可変長のメモリブロックで,開始番地を示すベース・レジスタとセグメントの長さによって割り当てる(図1)。一方,最近のオペレーティング・システムのほとんどが採用するページング方式(図2)は,メモリを固定長ブロック(x86では4Kバイト)のページに分割し,ページ番号だけで割り当てる(実際には,ページ番号ではなくアドレスをそのまま使うことが多い)。


図1●セグメント方式のメモリ管理


図2●ページング方式のメモリ管理

 セグメント方式は管理が面倒だが,メモリ利用効率はよい。一方,ページング方式は単純だが,無駄が多い。例えば,1Kバイトのメモリブロックを割り当てる場合を考えてみよう。セグメント方式ではセグメント長を1024バイトにすれば無駄なく割り当てられる(実際にはそれほど小さい単位でセグメントを割り当てることはあまりない)。一方,x86プロセッサの場合,1ページは4Kバイトだから,最小単位である1ページを割り当てても3Kバイトの無駄が出てしまう。

 インテル初の16ビットプロセッサ8086の登場時点では,メモリはまだまだ高価であった。さらに,8ビットプロセッサ8080との互換性も重要であった。セグメント方式の場合,セグメント長を64Kバイトに設定すれば,ベースレジスタからのオフセットを8080のアドレスと同等に考えることができる(図3)。こうした2つの理由から8086でセグメント方式が採用されたのだと思う。


図3●セグメント方式と8080互換メモリ空間

 8086の最大の失敗は,セグメント方式の採用ではなく,セグメントの最大長が16ビットに限られた点である。俗に言う「64Kバイト・バリア(障壁)」である。しかし,64Kバイト・バリアを超えるには,16ビットを超えるレジスタが不可欠である。8086という16ビット・プロセッサには荷が重い。ほぼ同時期に発表されたモトローラのMC68000は,内部構造を32ビットにすることで,24ビットの連続メモリ空間を確保し,当時のSunやMacintoshなどに広く採用された。しかし,商業的により成功したのは明らかに8086およびその下位版の8088であろう。

 プロセッサに限らず,アプリケーションであっても,アーキテクチャを決定するのは難しい。技術的に優れたものが実用的とは限らない。今は実行効率が良くても将来の技術革新でかえって問題を起こすかもしれない。Windows 3.1のアーキテクチャを見て,「将来を見る目がなかった」と批評するのは簡単である。しかし,当時の事情を考えると,それほど悪くもなかったのではないかと思う。

 システム・アーキテクチャは,現在の状況と将来の技術革新の両方を考えてバランスを取る必要がある。Windows 3.1のアーキテクチャは,現在の視点で見ると多くの問題がある。こうした問題を単に「間違っていた」と切り捨てるのではなく,当時の何がそうさせたのかを考えることが重要だと思う。それは,きっと現在設計しているシステムの将来像のヒントとなるに違いない。歴史を学ぶことは,過去を知ることが目的ではなく,将来を導くことが目的なのだ。