CPU実験: ライブラリのバグを晒す
# この記事は、2015年12月8日にYahoo!ブログへ投稿した記事を、Yahoo!ブログの終了に伴って2019年8月に移行したものです。
CPU実験 Advent Calendar 2015の記事です。
僕はコンパイラ係をしています。コンパイラ係関係の仕事の1つとして「ライブラリを書く」というものがあります。具体的に言うと、I/O系の命令や三角関数などの関数を、アセンブリやmin-caml言語などで書くことになります。
この記事では、僕がコンパイラを書くにあたって遭遇したライブラリのバグについて書きつつ、1stコンパイラのデバッグにかけた期間のラスト1週間がどんな感じだったのか書きます。多少記憶が前後しているかもしれませんがそこらへんはご愛嬌ということで。
☆ライブラリがすべからくバグっていた
僕はライブラリ関数をアセンブリで書いたのですが、眠たい眠たい言いながら睡眠前にちょっとずつ書いていたのが悪かったのでした。至る所buggyなライブラリは「コンパイラはちゃんとraytracerをコンパイルできているし、出力されたアセンブリも合法に見えるし、シミュレータ上でも正常に終了して画像を出力するのに、何かがおかしい」という状況を生み出しました。
市民、睡眠は義務です。眠たいときは寝ましょう。
もうどのライブラリがどのようにバグっていたのかはいちいち覚えていませんが、それぞれのライブラリ関数がどのような出力を吐くのか調べるために適当な入力のもとでグラフを書いた画像が残っていたので、これを貼ってお茶を濁します。
はじめにバグっていることが発覚したライブラリはcosでした(11月9日)。
どうみてもcosのグラフですね。間違いない。
多少手を加えると下のグラフのようになりました。タイトルがsinとなっていますがcosです。
このとき調子に載って同時にatanをプロットしたら痛い目に遭いました。
まあこれはすぐに直りました。
☆画像だなあ
11月10日にmandelbrotが動いたので、そのままの勢いでraytracerを動かしました。
綺麗なtron.ppmですね。
☆三角関数だけじゃなかった
floorもバグっていました(11月10日)。floorは何も考えずに実装しているとバグを生むので注意してください。
床関数(穴だらけ)。
このあたりのコンパイラデバッグ期間はつらかったです。ライブラリに限らず無限にバグが生まれていて悲しかった。しかもその9割は僕の不注意による非本質的な、typoなどのバグだったのでしょんぼり。
コアが既に完成していて、実機でも先ほどのレイトレース画像と同じ世紀末的画像が出力されることが再現されていたので、焦りがありました。
11月13日、floor, i2f, f2iなどのライブラリ関数がきちんと動くようになりました。
☆三角関数ふたたび
このあたりからFPU係の人がデバッグを手伝ってくれるようになりました(11月14日)。cos/sinの誤差を全数調査したところ、さっきのグラフではうまくいっているように見えるものの、実は無茶苦茶誤差っていることが分かりました。
なんか角が生えていますね。誤差だけ表示してみましょう。
グラフだと分かりにくいのですが、pi/4周期で誤差が大きくなっています。cosの実装上どこが誤差を生んでいるかはすぐに分かったので後はひたすら自分の書いたバグアセンブリを読みました。
☆うごいた
ライブラリを直して、CPU実験のレギュレーションを満たしていることを全て確認してもまだ動きませんでした。emit.mlを何回も読み直しました。バグを見つけてコミットしました。
そうしたら動きました(11月16日)。
最後に見つけたコンパイラのバグは、1箇所だけ浮動小数点数レジスタ移動命令fmovのsourceレジスタとdestinationレジスタの向きが逆になっているというものでした。
同じ日に実機でも完動しdiffは0で狭義完動となりました。
おしまい。
教訓: 眠いときは寝る。ISAを100回読む。
コメント
このページへのコメントはこちらまで (GitHub Issueに飛びます)