こんにちは、川合です。 不定期になりつつある報告です。・・・ところで、これを楽しみにし ている人はいるんでしょうか?長ったらしくて嫌がられてたりして・・ ・。まあ、とりあえず、誰か一人くらいは読んでくれるだろうと期待し て、今日も書きます(迷惑だったら言ってくださいね)。 最近やったことは、obj2bim3をMinGW + GO/win32でコンパイルしてみ たことです。具体的な手順は以下の通りです。 ・MinGWで-Eオプションでプリプロセスのみをやる ・その出力ファイルをGO/win32のcc1.exeにまわしてアセンブラソー スを得る ・MinGWに付属のアセンブラでアセンブル ・lcclnkでリンク なんでこんなことをやったのかというと、まず、プリプロセスについ てはデフォルトインクルードパスがよくわからなかったので、MinGWに 任せてしまいました。インクルードパスが分かれば、GOのcc1やcpp0で もできると思います。 リンクは、ldがやたらと大きなバイナリを生成したがるので、それを 嫌っただけです。ランタイムが大きいみたいです。 で、コンパイルに当たっては、ちょっと試行錯誤しました。 最初は、いつも通り-O2でやっていました。すると、許せないことに lcclnkを使っても結構大きなバイナリになるんです。これならlcc-win 32を単独で使った方がいいくらいです。「あれ?gccの最適化能力って 少なくともlccより上じゃなかったのか?」と思いつつ、試しに-O3をや ってみました。おお、出力結果が違う!ということは最適化レベルは -O3まであったのか!と分かったのですが、許せないことに-O3ではさら にでかくなっています。 むう、gccって駄目なのかもしれない・・・と思いつつ、出力された ソースを見てみました。なんということか、やたらと不要な32バイトア ラインが入っています。何でこんなものをいれるのか、こんなことしな くていいのに。そもそもcharを32バイトアラインすることにどういう効 果があるのか。と思ってあれこれいじっているうちに、-Osというサイ ズ優先のコンパイルオプションを思い付きました。 いや、実は前から-Osは知っていたのです。その時にcc1やcc1plusで 試してみて、-O2に対してわずか1%しか効果がなかったので、気休め程 度のオプションだと決め付けてしまったのです。・・・ところが今回は 効果があって1KBほど小さくなりました。これでlcc並みです。なんだ〜 -Osオプションは使えるじゃないか〜。gccよ、駄目だなんて言ってごめ んよ、と心の中で謝っておきました。 どんなソースを出しているのかとアセンブラソースを見てみると、う ーん、コード部は良くできているようですが、データ部の32バイトアラ インが残っています。なんでだよ。速度よりもサイズだって言っている のに、これはないでしょう?勘弁してよ〜。このアラインは消せないの か。こんなのおせっかいだよ。・・・試しにテキストエディタの置換で 消してみたらサイズが300バイトも改善しました。うーん、これは何と かしたい。これが解決できなければ僕はGOを推奨できないよう。 で、実は根本的な解決方法が分からなかったので、対処療法に乗り出 しました。与えられたテキストから"\n\t.align 32"という表現を探し 出して、"\n\t#align32"に置き換えるという、実に単純なアプリを書き ました。cc1からasにかける前にこの処理を施すことにして、とりあえ ず自動化できました。 こうして昨日のobj2bim3.exeはできたのです(上の操作以外にもUPX をかけるなどの処理もしましたが)。 さてその後、align 32の処置に気をよくした僕は、この処置を入れて cpp0.exe、cc1.exe、cc1plus.exeを-Osでmakeしてみたらどうだろうと 思いました。やってみました。それぞれ1割くらい小さくなりました。 おおなんということか、今までパディングのせいで1割も余計なサイズ になっていたわけです。ということで、現在のGO/win32のサイズは次の 通りです(括弧内は今までとの差)。 cpp0.exe 131KB (-12KB) cc1.exe 2.51MB (-260KB) cc1plus.exe 2.95MB (-320KB) もちろん、このalign 32を削ったcc1でも、obj2bim3などのコンパイル には支障ありませんでした。多分機能的には問題無いと思います。 また、こんなテストもやってみました。invader2.cをcc1でコンパイ ルして、asでアセンブルして、あとは今まで通りでやってみました。in vader2.cというのは、全然最適化していない普通のソースです(詳しく は、ぼやきの2001/08/03号のinvader対決の表を見てください)。 lcc-win32で-Oだけだと2735バイトですが、GO-C/win32だと「-Osとal ign 32の自動削除」で2630バイトです。ソースをいじることなくあっと いう間に105バイトも減るのはすばらしいことです(3.8%です)。やっ ぱり最適化は強そうです。もっともどちらもtekで圧縮して比較するな ら差はなくなってしまうのですが。これはしょうがないです。 なお、OSASKアプリのコンパイルの場合はインクルードファイルは全 て自前のものを利用するのですから、MinGWは不要です。プリプロセス は自前でできます。アセンブルにas.exeが必要なのは変わりませんが。 OSASK ver.3.1では、pokonやwinmanもGO-C/win32でコンパイルしてみ るつもりです。どのくらい効果があるのかは分かりませんが。 うーん、こうやって書き並べてみると今の段階でもGO-C/win32は多少 は使い物になりそうですねえ。使ってみたい人はいますか?何人かいる ようでしたら、ここらでアルファリリースします。 それでは。 -- 川合 秀実(KAWAI Hidemi) OSASK計画代表 / システム設計開発担当 E-mail:kawai !Atmark! imasy.org Homepage http://www.imasy.org/~kawai/