CPU実験まとめ。
昨日CPU実験の発表会がありました。私たちのチーム「地下詰妖精」はコンパイラコード18.407秒、ハンドコード17.085秒で歴代の記録を更新し優勝しました。
私はコンパイラ係を担当しHaskellでML言語のコンパイラとアセンブラの製作をしました。
この半年は一ヶ月以上家に帰らない月があったりと、非常に充実(?)したものでした。
来年からCPU実験の内容が変わるので、最後に何か面白いことをやりたいという班結成当初の目標の一つ目は達成できたのではないかと思います。
多分この班が初めて行った事。
- 実験基盤でゲームを作る
- レイトレーサのコードの徹底研究
- CADソフトの作成
- arc君
- コンテストで使用するSLDファイルをリアルタイムでレンダリングしたり、編集したり、検査したりする機能があるソフト。uemura君のC版エンジン搭載。
この実験をしてて一番良かったのは学科のすごい人達と共に作業が出来たという事でした。
単位と全く関係のないことにも本気を出せる、プログラミング好きなメンバーが集まったすごく良い班でした。
個人的にはソフトウェア係のuemura君にものすごく感謝しています。彼のデバッグ技術と最適化のアドバイスに助けられてばかりでした。
あと、arc君のプレゼンに対する熱意はすごいと思いました。泊まり込んでプレゼン資料のロゴとかイラストを描いたりしてくれました。
個人的にはこの実験で
という収穫がありました。
目標の二つめは10秒切りなのですが、それが達成できなかったのはとにもかくにもコンパイラ係である私の未熟さ故で、班員のみんなには申し訳ない気持ちです。
去年7月頃からHaskellの勉強を初め、すらすらコードを書けるようになるまで4〜5ヶ月かかり、並行してコンパイラの勉強も進め、結局初めて本番用のコンパイラコードが動作したのが1月になってから。
それから各種最適化を急いで実装するもまだアイデアがある段階で期限切れになってしまうという残念な結果になってしまいました。
総インストラクション数は14億4,5千万くらいだったかと思います。過去のコンパイラ係の資料とか見てみると12億切っていたりするところもあるのでしょぼいです...orz
コンパイラがやっている最適化等に関してはいずれ資料をアップするので良いとして、Haskellでコンパイラを書いてみての感想です。
- スラスラコードを書けるようになるまでが長い
- 実行時の消費メモリが膨大
- 予想はしていたけれど想像を越えていた。使用メモリが増えていくと突然実行時間が急激に低下する。
- 終了間際にかなり頑張って実行時プロファイル情報を利用した大域的部分冗長性の除去を実装したら実行にン時間かかりコンテストまでにコンパイルが終わらないという事態に。これが高速に動けば上の記録も変わっていたはず。部分冗長性除去なしだとコンパイル時間は10秒〜30秒くらい。
- テーブルにIOArrayを使用したり正格性の指定とか色々気を使ったけれどもなかなか改善しなかった。
- 一部のアルゴリズムの記述が非常に簡単になる
来年のコンパイラ係へ
- とくにかく早い段階で動くコンパイラを作った方が良いです。私はminCamlを改造したもの、ocamloptを改造したものを作成した後に、Haskellでのコンパイラを作成しました。
- 本番用コンパイラを別に作るという場合にも、ここでの経験が助けになると思います。
- 0から書いた方が絶対に勉強になります。
- 既存のコードに修正を加えるのと、丸写しでも自分で書くのでは全然違うと思います。
- 良いハードウェアを生かすも殺すもコンパイラ次第です。来年はハードウェアが豪華になるらしいので、ハードウェアに並列化などの機能が搭載されるようになるかと思います。それらをどれだけ生かせるかはコンパイラ係に懸かっていると思います。
- ハードウェアが自分でスケジューリングとかするようになってしまったら、コンパイラの仕事がなくなってしまうかもという話もありますが(笑)
- 折角コンパイラを作るのであれば、何か一つは高度な最適化に挑戦してもらいたいです。データフロー方程式を解く大域的な物とか。骨が折れますが、やっぱり最適化の効果が高く、おもしろく、勉強になると思います。
- オープンソースのコンパイラコードで参考になるもの
- ocamloptはあまり参考にしない方が良いです。実は大した最適化があまり行われていません。また、仮想機械語以後が独自の拡張を追加しにくいような形になっています。C--の最適化部とかレジスタ割り当てとかはとても参考になります。
- SML New JerseyのFLITというとこのコードが読みやすくて参考になると思います。Loop unrollingとかCode Hoistingとかいろいろ揃ってます。CPS変換とかも。
- COINSというプロジェクトがあるんですが、中間機械語以降が参考になるかもしれません。自分はデータフローの解析とかでちょっと読みました。先進的な最適化をしたくなったら、ここを読むしかないです。
- 大学の課題をちゃんとやりましょう。
- 好きな事ばかりやりすぎて、大学の課題を何もやってなかったので単位を落としまくりました。
- CPU実験が終わって気が抜けて現実に戻った後に鬱になります。
CPU実験は終わっちゃいましたが、来年までにコンパイラコードで9秒を切るという使命が出来たので延長戦をすることにしました。
まず、試行錯誤しながら書いたためぐちゃぐちゃになったコードの整理と高速化(実装言語を変えるかも)をして、やりたかったけれども間に合わなかった大域的なスケジューリング・ポインタ解析(をして間接参照をなくす)、既存最適化の見直し、この班のハードに特化した最適化とかをしていこうと思います。
それからコンパイラやHaskellに関してこの半年に勉強したことを、ここに少しずつ書いていこうか思います。
Haskellプログラムの高速化に関してもいろいろと実験とかしたいと思います。