その昔、Turbo Pascal というプログラム言語があった。
…この言い方はちょっと違うか。
Pascal というコンピューター言語があって、その処理系の製品として、Turbo Pascal があった。
Pascal というのは、もともと教育用に考えられた言語だ。
といっても、わかりやすくなっているけど非力、というようなことはなくて、非常に強力。
祖先は ALGOL で、C と同じ。だから、プログラムの組み方も C と似ている。
違うのは、C はハードウェアを直接叩けて、システムクラッシュさせるのも自由気ままにできるのに対し、Pascal はハードウェアをできるだけ隠蔽するように作られているので、システムクラッシュが起こりにくいこと。
隠蔽する、というのは手間がかかることなので、パフォーマンスは C が上。
プログラムを組む上でも、Pascal は「比較的厳密な」文法を求められるのでバグが出にくい反面、いちいち入力が面倒くさかった。
趣味のプログラマーにとってはバグなんて多少出てもいいし、厳密に書かないと動かないのは面倒くさいので嫌われた。
そんなわけで C 言語が幅を利かせるようになり、「類似言語」であった Pascal は下火になるのだが、Pascal 自体が非常に強力な言語であった、という事実は変わらない。
強力さのひとつに、言語設計のうまさがある。
プログラムは、必ずボトムアップで書かなくてはならない。
わかりやすく言い換えると、関数は定義してからでないと使えない。
「とりあえず関数の呼び出しを書いといて、あとで関数の実体を書く」は、原則として許されない。
これによって、関数が呼び出されるときには、すでに関数の定義が終わっている。
同様に、変数も使われる前に定義されている。
C言語では、どこで関数が定義されているかわからないので、コンパイル時に少なくとも2回はソースを読まなくてはならない。
1回目で定義を全部把握して、2回目で実際のコンパイルを行う。
でも、Pascal の設計では、1度ソースを読めばコンパイルが完了できる。
で、冒頭の Turbo Pascal。
「Turbo」と名づけただけあって、コンパイルが速かった。
…「速い」なんてもんじゃない。コンパイルしていることに気づかなかった。
なにせ、Turbo Pascal には専用のエディタがついていて、エディタの上で F5 キーを押すと、プログラムを実行できるのだ。
BASIC のような、インタプリタ言語の感覚でプログラムを組むことができた。
これはつまり、エディット中なのでメモリ上に入っているソースをそのままコンパイラに渡し、コンパイラは1パスでコンパイルを行い、生成後のバイナリはメモリに載せたまま実行していた、ということだ。
ディスクアクセスがないので、非常に速い。
Turbo Pascal を作った Borland 社は、C 言語のほうが人気が出たために Turbo C も作った。
でも、こちらはいまいち。当時のほかの C 言語処理系よりも高速にコンパイルができたが、C 言語の仕組み上ファイルを多数読み込まなくてはならず、コンパイルも1パスではできず、「インタプリタ感覚」とはいかなかった。
大学のとき、アルバイトしていたゲーム会社で、グラフィックデータの整理を任されたんで、Turbo C を借りて2~3日でツールを作って、大量のデータ整理が簡単にできるようにしたっけ。
バイトの仕事として雑用を任せたら、汎用のツールを作ってしまったので驚かれて…社長から、大学辞めて働かないかと誘われました。
腕を認められたわけでうれしかったけど、大学やめる気はなかったので、翌月にバイトやめて逃げ出してしまいました。
今ではそれなりに有名な会社だけど、社長元気かな。
と、ここまでは長すぎる前フリ。
Turbo C Compiler のコマンド名は tcc だったけど、今回の話のテーマは、同じ tcc というコマンド名を持つ、Tiny C Compiler 。
2004 年には最初のバージョンがでているようなので(もっとも、2002 年には otcc という名前で前身となるプログラムがある)、ここで取り上げるのも「いまさら」なのだろう。
僕は3年位前に tcc の存在は知っていたのだが、Tiny と名前についているくらいなので、「コンパイラの作り方の教科書に出てくるような、C 言語のサブセット」だと思っていた。
実際、otcc はサブセットだったらしいのだが、tcc は ISO の規格にのっとった、フルセットの C 言語になっている。
そして、tcc がすごいのは、Turbo C 並にコンパイルスピードが速いこと。
ファイルを多数開くのは C の特性上仕方がないが…1ファイルで完結する短いプログラムであれば、TurboPascal並と言って差し支えないだろう。
この速さを活かして、ソースをコンパイルして、バイナリをファイルに吐き出さないでメモリ上においたまま実行、ということができる。
つまるところ、C 言語をインタプリタ言語のような気楽さで使えるのだ。
もっとも、生成されるソースコードの品質は低い。
速度を活かして開発して、出来上がったら GCC などで最適化したバイナリを作る、というのが正しい使い方なのだろう。
というわけで、早速インストールしてみる。
Unix (僕の場合、Linux の CentOS 5.5)にインストールするには、ソースを展開して、
./configure
make
make install
で終わり。
この場合、GCC でコンパイルされる。
せっかくなので、コンパイル時間を計ってみる。
time make
とすればよい。
make するたびに、make clean して元の状態に戻し、3回計って平均を取ってみた。
real 0m19.858
user 0m18.955
sys 0m0.689
重要なのは、user の値。0分18秒955。
出来上がったバイナリサイズは、331769 byte。
さて、次に、出来上がった tcc で tcc 自身をコンパイルしてみる。
./configure -cc=tcc
あとは同じでよい。同様に3回やってみて平均。
real 0m0.395
user 0m0.318
sys 0m0.047
速い。59倍速。こんなに速すぎると測定誤差もあるだろうから、何倍、に意味はなさそうだけど。
出来上がったバイナリサイズは、410056 byte。
バイナリサイズは2割り増しだ。
gcc と違って最適化がされていない(もしくは甘い)ので、コンパクトさで2割違う、ということだ。
続いて、tcc でコンパイルした tcc で、tcc をコンパイル。
これで、tcc が生成したバイナリの速度品質がわかる。
real 0m0.777
user 0m0.649
sys 0m0.052
遅い。先ほどの倍以上の時間がかかっている。
gcc と違って最適化がされていないので、速度で2倍違う、ということだ。
出来上がったバイナリサイズは、411324 byte。
…あれ? tcc コンパイル、という点で同じなのに、さっきと違う。
よく見たら、tcc をコンパイルすると、tcc が使用するライブラリも一緒に生成されていた。
つまり、最初に tcc でコンパイルをした際、使用されたライブラリは gcc でコンパイルされたもので、これが最終的なバイナリにも含まれていた、ということ。
2回目の今回、ライブラリも tcc でコンパイルされたものとなったので、これが本当の「tcc でコンパイルされた」サイズ。
念のため、もう一度 tcc でコンパイル。
real 0m0.763
user 0m0.635
sys 0m0.075
速度はほとんど変わらず、誤差範囲。
出来上がったバイナリのサイズも先ほどと同じで、念のため diff したが、完全に同じものだった。
というわけで、結論。
tcc のソースをコンパイルする、という限定的な条件の試験だが、以下の結果が得られた。
tcc の生成バイナリは、gcc の生成バイナリよりも、コンパクトさで2割、動作速度で2倍程度劣る。
しかし、tcc によるコンパイル自体は、gcc よりも 20倍以上速い。
余談だけど、tcc 作った人は、FFmpeg とか、QEMU とか、A PC emulator in Javascript とか作った人と同一人物。
FFmpeg といわれてもわからなくても、携帯動画変換君や MEncoder 、VLC Player など、数え切れないほどの「動画関連ソフト」が、内部に FFmpeg を持っている、と説明すれば、すごいソフトであることが理解されるでしょう。
また、QEMU も、Xen や kvm など、Linux に組み込まれた「仮想化技術」のコアになっています。
A PC emulator in Javascript は、その名のとおり、QEMU を Javascript で実装してみた、という実験です。
リンク先に進むとわかりますが、Linux が起動し、tcc でソースをコンパイルできる環境が整います。
これ、「そんな感じに見えるフェイク」ではなくて、本当に動作する Linux なんですね。
chrome とか、最近のブラウザ使えば、ベースマシンの CPU 速度が遅くても、それなりの速度で動作します。
あと、2009 年時点での、円周率の計算桁数で世界記録保持者でした。2兆7千億桁。
先日、日本人が10兆桁計算して、現在はこれがトップですが。
なんか…すごいなぁ。「面白がって」プログラムを作っている感じが、すごくする。
そして、その面白がりが非常に有用で、世界を変えるほどの力を持っている。
本当のハッカーって、こういうことなんだろうな。
後日追記 11.11.18
本文中に書いた「大学時代にバイトしたゲーム会社」ですが、それなりの規模になって某人気ゲームシリーズなどを作っていたのですが、5年ほど前に廃業しているようです。
ネットで調べて知りました。
同じテーマの日記(最近の一覧)
関連ページ
スーパーファミコンの発売日(1990)【日記 13/11/21】
ニクラウス・ヴィルト 誕生日(1934)【日記 16/02/15】
別年同日の日記
申し訳ありませんが、現在意見投稿をできない状態にしています。 |