gccだってもちろん非常によくIntelチップ用に最適化されたコードを出してくれるのだが、基本的には486以上のプロセッサはすべて486としてしか扱っていない(と思う)。たとえば、kernelのソースを展開すると、/usr/src/linux/arch/i386/Makefile などがあると思うが、このファイルを見ると 486 以上のプロセッサを使った環境では、常に -m486 というオプションを付けてコンパイルされるようになっているのがわかる。386 の場合は(当然だが) -m386 が使われている。
PGCCを使うと、このプロセッサの指定に-mpentium という呪文が使えるようになるのだ。ね?怪しいだろ〜? コンダラを引く者として、これは使うしかあるまいて(笑)
PGCCはつい最近、Version 1.1b がリリースされたんだけど、オレの使っているのは実は 1.0.3a だ。PGCCのソースはEGCSへのパッチという形態で公開されているので、PGCCを手に入れるには、まずEGCSのソースを手に入れ、展開し、PGCCのパッチをあててmakeする、という手順が必要になる。もちろん、いくつかのプラットフォーム向けのバイナリも用意されているので、それを落してくることもできる。
PGCCはまさに開発の真最中で、非常に頻繁に、それこそ2週間に一回くらいの頻度でSnapShotがリリースされている。また、SnapShotではなく、リリースという形で公開されるものにはバージョン番号がちゃんとつくことになっている。まぁSnapShotとは言っても、どっかの会社のプリベータとかなんとかいう定義の曖昧なシロモノとはまったく違って、当然ちゃんと動作はする。とはいえ、オレはPGCCのSnapShotからバグを見つけたりする技能はないし、追っかけをするつもりもなかったので、一応のリリースとして公開されていた 1.0.3a を持ってきてmakeしてみたのだ。
赤帽5.1にも最初からEGCSのパッケージは含まれているのだが、そのバージョンは1.0.2だった。なので、EGCS-1.0.3aのtarballとPGCC 1.0.3aのパッチを落してきて、赤帽のEGCS 1.0.2のパッケージをベースにしてPGCC-1.0.3aのパッケージを作ってみた。GCCとは共存することができるが、EGCSとは共存できない。ファイル構成がEGCSとほとんど同じだからね。PGCC 1.0.3aのパッケージを作る SPEC ファイルだけ(セコイのぅ)パッケージ置場に置いたので、もしもPGCCを使ってみたい赤帽な人は、持ってって参考にしてくれたらいいと思う。
PGCCを正直にmakeすると、確かgccかegcsかを上書きしちゃったと思う。コマンドラインで -V 2.7.2.3 とか付けると、gcc 2.7.2.3として振る舞うように作られているそうなので、これでも確かにいいといえばいいんだけど、Makefile とかをいちいち書き直したり、環境変数を設定したりというのはうざったいし、正真正銘の gcc 2.7.2.3 を残しておいて、普段はそっちを使うほうがなにしろ安心だ。そこで、SPEC ファイルの方でツジツマを合わせて pgcc というコマンドとしてインストールされるようにした。
今、オレの赤帽で gcc -vを実行すると、
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.7.2.3/specs
gcc version 2.7.2.3
と表示され、pgcc -vを実行すると、
Reading specs from /usr/lib/gcc-lib/i586-redhat-linux/pgcc-2.90.29/specs
gcc version pgcc-2.90.29 980515 (egcs-1.0.3 release)
と表示されるようになっている。
さて、お楽しみのPGCCがパッケージ化できたまではよかったのだが、コイツを使って、うまいこと他のパッケージをPentium向けに最適化して作るやり方がわからず(愚かな…)、また他にもやりたいことがあったので、しばらくPGCCは塩漬けになっていた。が、ここに救世主が! 誰あろう佐藤さんである。そう。赤帽な我々にwcsmbsの教えを説き、オレをコンダラ道にいざなってくれたお方だ。今回もオレに秘伝(笑)を授けてくれた。Pentium専用パッケージの作り方である。
あ、ここで強く注意を促しておくが、この秘伝はただの秘伝ではない。これを読んで、もしも誰かに説明するようなことがあったなら、必ず秘伝(笑)と書かねばならぬ。口で説明するときはもちろん「ひでんかっこわらいかっことじ」などと言うべし。いやマジで。なにしろただの秘伝ではないのだ。だって、佐藤さんに「この技を教える上で、絶対に守ってもらいたい条件」って言われちったんだもん(笑)
で、その秘伝(笑)だが、まず.rpmrcという隠しファイルをホームディレクトリに用意する。まぁ、このファイルはrpmなパッケージを作れる人ならすでにあるのではないかと思う。このファイルに1行追加する必要があるのだ。オレの場合はこうなっている。
topdir:/usr/local/src/redhat optflags: i386 -O2 -m486 -fno-strength-reduce optflags: i586 -O6 -mpentium -fno-strength-reduce
通常、rpmなパッケージを作成するときは、/usr/src/redhat というディレクトリがすべての作業の中心となるのだが、オレの赤帽では、どうしてもrootで作業しなければならないパッケージを作る場合にだけ /usr/src/redhat を使うようにしていて、普段は一般ユーザで作業をするために /usr/local/src/redhat というディレクトリを用意してそっちでやっている。まぁそんなに神経質にならんでもいいのだが、怪しいパッケージの中にはひでぇのもあって、パッケージを作る過程で変なところにインストールしにいっちゃっったりするものもあるんでね。
rootで作業していると、気が付かぬうちにすべて通ってしまうので、後からなんじゃこりゃということになるのはいやでしょ。また、赤帽では基本的に/usr/localの下は使わないようになっているので、割り切って/usr/localの下にはredhatしか置かないようにしている。/と/usr/localにはそれぞれ違うパーティションをマウントしているので、/usr/localのパーティションを丸ごとバックアップすれば、自分でmakeしたパッケージや、そのソースなどが一まとめにバックアップできて便利なのだ。
あ、脱線してしまった。秘伝(笑)に戻ろう。大事なのは3行目の
optflags: i586 -O6 -mpentium -fno-strength-reduceだ。i586、つまりpentiumの時は、コンパイラのオプションとして -mpentium が指定されるように設定しておくのだ。そして、オレの場合は topdir に /usr/local/src/redhat を指定しているので、/usr/local/src/redhat/RPMS の下に i586 というディレクトリを掘っておく。i386 と noarch というディレクトリはすでにあるはずだ。ここに i586 を追加するのだ。こうしないと出来上がったパッケージを置く場所がないのでエラーになってしまうからね。
さて、.rpmrcも用意した、i586のディレクトリも掘った。いよいよPGCCでパッケージをソースから作ってみるのだが、実際にはrpmコマンドに対してオプションを指定して行う。たとえば、hogehoge パッケージを作るために、hoge.spec を使うとしたなら、コマンドラインで
rpm -ba --buildarch i586 hoge.spec
などとして、i586だぞ、と明示的に指示してやるのだ。こうすることによって、hogehoge-1.0.i586.rpm などというファイル名のパッケージが RPMS/i586 の下に作成されるワケだ。
だけど、肝心なPGCCをどうやって使わせればいいのか?というと、これはもうパッケージ毎に異なるとしかいえない。configure で Makefileを作るか、xmkmf で作るか、またはいきなりmakeしちゃうか、のどれかだと思うが、configureを使うものが一番多いのではないかと思う。まぁconfigureでMakefileを生成するようになっていたとしても、中を見てみないことにはハッキリしないのも確かなのだが…
--buildarch i586 オプションを付けて rpm を実行すると、SPECファイルの中で場合分けすることができる。例をあげると、
%build %ifarch i586 CC="pgcc" export CC %endif CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr make
などというように記述しておけば、--buildarch i586 オプションを付けたときはpgccが使われて i586.rpm が作成され、なにも指定しない場合は普通に gcc が使われて i386.rpm が作成されるようになる。RPM_OPT_FLAGS は .rpmrc に書いたものが使われるので、自動的に -m486 と -mpentium が切り替わるので意識する必要はない。
まぁ、configureを使っていても、内部で CC を gcc に決め打ちしていたり、CFLAGS を明示的に(プログラムの都合などもあるだろうし)指定してしまっているものも多いから、そういう場合はどうするかというと、PGCC で -mpentium オプション付きでコンパイルするようにMakefileを手で修正し、もともとのMakefileとの差分をdiff -uNrなどで取って、パッチファイルを作るのだ。そして SPECファイルに Patch: hogehoge-1.0.pgcc.patch などと追加しておき、
%setup %ifarch i586 %patch -p1 %endif
などとして、i586 なときだけパッチをあてるように細工をしておく。こうしていつでも、i386 と i586 を選択できるようにしておくのだ。
PGCCでコンパイルしたものが、必ずGCCよりもよい結果を出すのならこんなことはしなくてもよいのだが、場合によってはGCCでコンパイルするよりも遅くなってしまうようなプログラムもあると言われているし、なにより、GCCでコンパイルしたものは正しく動作するのに、PGCCでPentium用に最適化すると遅くなるどころかcoreを吐いてブチ落ちてしまうものさえあるようだ(実際あったよ)。また、PGCCなど使っていない人に対してsrc.rpmを公開したりする場合もある。その都度パッケージを作り直すのは手間だしミスも混入しやすくなるので、なるべく共通化し、いつでもPGCC版とGCC版を比較できるように保っておくのは大事だと思う。
というワケで、今まで自分でパッケージ化したものはすべて、GCCでi386向け、PGCCでi586向けにパッケージを作成できるようにSPECファイルを修正してみた。PGCCでコンパイルした方をインストールして、今使って具合を見ているところだ。kernelももちろんPGCCで-mpentium -O6を付けて再構築した。まぁベンチ・マークとか厳密に取ったワケじゃないので、全然信憑性はないんだけど、いろいろと気が付いたことはあったよ。
PGCCでは、-O6 がおすすめの最適化のようなので、デフォルトで-O6を使うように .rpmrc に設定しているのだが、-O6 でコンパイルするとどうも正しく動作していないものがいくつかあった。動作しなかったのは
1. XEmacs-20.4
これはパッケージを作ること自体できなかった。XEmacsのmake自体はできたのだが、--batch オプション付きで起動し、elispのコンパイルをさせるとcoreを吐いてブチ落ちてしまうのだ。どの.elでもなるワケじゃないのがいやらしい。まぁどっちにしろXEmacsは遠からず捨て去るつもりなので、黙って -O2 でコンパイルし直したら正常にパッケージもできた。
2. GIMP-1.0
GIMPもなんだかちょっと変だった。一応、一通りの機能は動作を確認できて、script-fuなども動いたんだけど、なぜか起動時に表示される Tip of the day のダイアログボックスをcloseできないのだ(笑) closeボタンを押すとcore吐いてブチ落ちる。この機能だけなんだよね。変なの。まぁGIMPもオレ的にはそんなに頻繁に使うわけでもないし、すでに1.1も出ているってことで、詳しい調査はしなかった。で、結局は -O2 でコンパイルしなおしたらちゃんと動くようになったのでそのままにしている。
3. leafnode 1.4
パッケージそのものはちゃんとできたのだが、fetchコマンドでnewsをspoolに取り込むと、途中で止まってしまう。ブチ落ちるんじゃなくて、何もせずにただ止まっているようにしか見えない。CPUを食ってるワケでもないし、さりとてパケットの一発も出てない不思議な現象。これも-O2でコンパイルしなおしたら収まった。
4. zlib 1.1.2
実は自分でmakeしたパッケージだけでなく、libjpeg、libungif、libtiffなどのグラフィクス関係、gzip、tar、zlibなどの圧縮やアーカイブ関係もPGCCでi586ようにコンパイルしなおしてみたのだが(笑) zlibは-O6でコンパイルすると、それ自身は問題ないのだが、install-info が core を吐いてお亡くなりになるようになってしまった。現象として確認できたのはinstall-infoの動作不良だけだが、zlibはPPxPなどでも使うし、なによりrpm自体がzlibを使っているので不都合があると非常に困る。これも-O2でmakeしなおしたところ、install-infoの不具合は収まり、PPxPもrpmも問題なく動作している(ように見える)。
5. XFree86 3.3.2+x-tt1.0
これ、実は結構期待していたのだが、ダメだった(笑) -O6 付きでコンパイルしたらXサーバが立ち上がらなくなってしまったのだ。で、ちぇっ、またかよ、と思って -O2 でコンパイルしなおした。一回パッケージを作り直すのにもXFree86なんてむちゃくちゃ時間かかるってのに。で、-O2 な方はちゃんとXサーバも起動でき、幸せが訪れたかと思ったのもつかの間、なんか遅いんだよね。体感上。なにか動きにキレがないの。で、あてにならないと知りつつも、軽くxengineなんぞを動かしてみると、以前計ったときの記録より、実際に10%くらい遅いでわないか!何度動かしてもコンスタントにそれくらい遅い。げろげろ。マジ?と思って真剣にx11perfで調べてみた。結果、捨てることにしたよ(笑) だって遅くなるんだもん。だもんで、XFree86はgccの方を今でも使っている。
上記5つ以外にpgccでコンパイルしなおしたものは、すべて -O6 で最適化したが、今のところ不都合は出ていない。といっても3〜4日しか使っていないが…。もちろんいきなりi586なパッケージを大量生産し、同時に全部突っ込むなどというバクチはせず、メインではないマシン(COMPAQノートPC)に、環境を壊してもいい覚悟で一つ一つインストールし、簡単に動作を確認し、処理速度の向上または低下、機能的な不都合がないか様子を見ながら入れたのだ。
自分でもよ〜やるわと思うが、現状ではkernelも、glibcまでもがPGCCの-O6でコンパイルしたものに差し替えられている。まぁglibcをPGCCでコンパイルしたおかげで劇的に速度が上がったか?というと、正直言って体感ではまったく区別がつかないと言えるだろう(笑)
だが、一応はこれでも極々簡単なベンチ・マークはやってみたんだよ。といっても、tar cvfを50回やって平均タイムで比較、とかgzip 50本とか(笑) で、大体において5%くらいは平均して速いようだ。入れたばかりのRubyも、サンプルプログラムをいろいろ動かしてみた範囲では、10%程度は速くなっているようだ。
Xサーバが遅くなっちゃったのはお笑いだったが、その他のGUIに関係するものはバッチ的に測定する手段がない(思い付かない)ので体感しか頼るモノサシがない。まぁプラシーボ効果バリバリだとは思うが、少なくとも明らかに悪化したのはXサーバだけだなぁ。最初は一瞬FreeTypeのライブラリを心配したのだが、Xサーバと同じようにFreeTypeライブラリを使うghostscriptは、繰り返してテストしてみたけど速度の向上が確認できたので、少なくともFreeTypeライブラリが足を引っ張っているということはないと思う。
お!?これは速くなったんじゃないか?と感じるのは Tcl/Tk を使うユーティリティ、Window Maker なんかもいい感じ。あ、Window Make はそっと0.20.1に上がっていて、パッケージ置場にあるんでよろしく。それと、GIMPは-O2なせいか、あまり変化を感じないなぁ。
あと、明らかに、数値的にも速くなったのは、実は8hz-mp3というユーティリティだ。もともとWin32用のソースなんだが、GCCやPGCCでもちょっと手直しすればコンパイルできるのだ。なんだかMP3技術のパテント関係でいろいろモメているようなので、パッケージ化はしたものの公開していないのだが、コイツはすごく速くなったぜ。
猿入ってしまい、調子にのって手持ちのCDを次々とMP3にして、COMPAQノートがディスクマンと化してたりするよ(笑)
WAVファイルからMP3にエンコードしてくれる数少ないオープンソースなエンコーダなんだけど、大雑把にいって1曲3分間のWAVファイルを、だいたい8分間の処理でMP3にエンコードしていたのが、PGCCでコンパイルしたものだと、コンスタントに6分を切るくらいの時間で処理できるようになった。これは嬉しいね。
そもそも、もうとっくに普及しちゃっているMP3に対して、今ごろになって特許の話を持ち出す(しかも「警告」という形で)なんぞ、たとえ正当だったにしても頭に来る話だ。事情はよくわからぬが、現時点では金目当てと断定しておこう。今のこのオープンソースのトレンドをわかってないのかねぇ。だから、もう少しパッケージのテストをして問題なければ、日本で8hz-mp3を改良して公開している染川 淳さんに連絡を取って、オレも8hz-mp3のrpmを公開しちまおうと思っている。
メール | 戻る |