プログラマyasuhoの隠れ家

某ソフトウェア企業に勤務するおじさんプログラマyasuhoです

GBAにはThumb命令


GBAのプログラミングに関しては、ある程度分かったつもりでいた。
ARMやGBAのハードウェアは、とても素直なので、理解するのもそれほど困難ではない。
もちろんサウンドや様々なスクリーンモードなど、理解していないところも多いのだが、自分の作る範囲においてはそれほど困らなくなった。
けっこうできるつもりで、うぬぼれていたのだ。


だが、それは単なるおごりであることが証明された。


GBAのCPUであるARM7TDMIは、32bit RISCプロセッサであり、命令長も32bitなのだが、実は命令長が16bitのThumb命令セットというのが存在する。
32bit命令は強力で、CPUのパフォーマンスを最大限に発揮することができるのだが、単純な命令などではどうしてもコードサイズが大きくなる。
これはRISCプロセッサのある意味宿命のようなものなのだが、その欠点を補うために16bit長の命令セットも用意されていて、これをThumb命令セットと呼んでいる。
パフォーマンスは32bit命令に劣るが、コードサイズを小さくすることができる。
プロセッサの性格上組み込みで使われるARMには、コードサイズを稼げるのは重要なことなのだろう。


32bitと16bitの命令は、混在して使うことが可能だ。
CPUのステータスレジスタ(CPSR)のTビットを立てると、それ以降の命令が16bit命令になる。
CPSRを復帰させると、元の32bit命令に戻る。
通常はジャンプやコール命令でこれらを設定し、関数単位で32/16を混在させて使う。
これにより、状況に応じて命令セットを使い分けるといったことができる。


Thumb命令の存在自体は知っていたのだが、なんとなく使うのが面倒で、今まで使ったことはなかった。
32bit命令の方がパフォーマンスが高いし、コードサイズがちょっと大きくなっても、それほどパフォーマンスに影響はないのではないかと思っていたのだ。
そんなわけで、アプリケーションでも全て32bit命令で作っていた。


だが、それは大きな間違いだったのだ。
ある日ふとThumb命令を使ってみようと思い、プログラムを再コンパイルして実行してみた。
その結果は歴然としていた。
Thumb命令を使っただけで、コードサイズは従来の75%程度になったばかりでなく、実行速度も目に見えて速くなっていた。


考えてみれば、GBAのROMは16bitバスなので、Thumb命令の方が効率よく実行できるのは明らかだ。
さらに改訂ARMプロセッサasin:4789833577、Thumb命令に関する説明の最初の方に、このようなことが書いてあった。

  1. ThumbコードはARMコード空間より70%小さくなる
  2. 16bitメモリでは、ThumbコードはARMコードより45%速い
  3. ThumbコードはARMコードより使用する外部メモリ電力が30%少ない

コードサイズが小さくなり、速くなるのは当然である。
さらに電力消費量まで少なくなるんだ。
16bitバスにはThumb命令で決まり、ということのようだ。


今までこのブログでは、何度かCPUパワーに甘えず、性能改善の努力をするべきである、と書いてきた。
だが、そう言っている自分自身がCPUパワーに甘んじてしまっていることを、今回思い知らされた次第である。
しかもこれはちょっと調べるだけで、分かることだ。


GBAに関してもそうだが、自分の努力不足を痛感した。
もっと精進が必要ですね。。。