x86エミュレータチームが劣悪なコードを発見し、エミュレーション中に修正
原題: The time the x86 emulator team found code so bad they fixed it during emulation
なぜ重要か
レガシーシステムのエミュレータ開発における実践的な最適化戦略と、不適切なコンパイラ最適化の影響を示す事例として、ソフトウェア設計・エンジニアリングの教訓を提供する。
Windowsのx86-32プロセッサエミュレータチームが、64KBのメモリを初期化するプログラムで異常なコード生成を発見した。コンパイラがループ展開を過度に最適化し、65,536個の個別の書き込み命令(各4バイト)を生成していた。結果として256KBのコードが64KBのデータ初期化に使用されていたため、エミュレータ側で検出・修正する特殊なロジックを追加した。
Windows開発の歴史に関する記事「The Old New Thing」で、Raymond Chenが過去のプロセッサエミュレータに関する逸話を紹介した。
この事例は、非x86プロセッサを搭載するシステムでx86-32互換性を実現するため、Windowsがバイナリ翻訳によるエミュレータを採用していた時代のものである。エミュレータはJITコンパイラのようにネイティブコード生成を行い、インタプリタ方式よりも高速処理を実現していた。
問題のプログラムは、スタックに約64KBのメモリを割り当てて初期化する処理が必要だった。標準的な実装方法は、スタックプローブで容量確認後にスタックポインタから65,536を減算し、タイト・ループで初期化するものである。しかし、当該プログラムを編集したコンパイラは、ループ展開を過度に行い、65,536個の個別の「メモリへのバイト書き込み」命令(各4バイト)を生成した。総コード量は256KBに達し、初期化データの64KBを大幅に超過していた。
この状況にエミュレータチームは強い不満を持ち、このような劣悪なコード生成パターンを検出し、タイト・ループに置き換える特殊な翻訳ロジックを追加することで対応した。コメント欄ではXbox 360向けのエミュレータでも同様の低効率なコード処理が多数存在したことが報告されている。