[OSASK 5249] Re: GO計画.

  こんにちは、川合です。

  不定期になりつつある報告です。・・・ところで、これを楽しみにし
ている人はいるんでしょうか?長ったらしくて嫌がられてたりして・・
・。まあ、とりあえず、誰か一人くらいは読んでくれるだろうと期待し
て、今日も書きます(迷惑だったら言ってくださいね)。

  最近やったことは、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/


ML番号でジャンプ
ML単語検索