ビットマップの糞仕様

ビットボードを使ったら、JavaScriptでさえあんなにライフゲームが高速になる。
MMXで書いたらさぞ速いだろうと思い、書くことにした。
まだMMX版は作っていないが、
VC++でunsigned long(32bit)を使い、とりあえず動くものを完成させた。
以前作ったMMXライフゲームは、1セルに1byteを使っていた。
表示にも1byte/pixelのビットマップを使い、SetDIBitsに直接渡すようにした。
これが(当時の自分の感覚では)猛烈に速く、
今回、1セル1bitにしたらどんなに速くなるかと期待が膨らんたのだ。
結果的に、SIMDアセンブラを使うまでもなく、C言語レベルで、
1024x768で60fpsを出してもCPU使用率が0%*1というものが出来上がった。
ライフゲームの計算をする部分はJavaScript版とほぼ同じコードの字面)
そもそもライフゲームの処理は軽いということなのだろうが、この数字は嬉しい。
もっとも、この方法はC言語の表現力が生きて、しかもアセンブラの表現力を必要としない。
ビット演算メインなので、アセンブラの手動最適化と同等の速さが既に出ていると思われる。
ビット数が倍のMMXを使っても、この2倍までは速くならないだろう。
さて、やっと本題だが、1bit/pixelのビットマップを使うときに思わぬ問題が待っていた。
1byteの中に8個のデータを入れるわけだが、何と並び順がビッグエンディアンなのだ。
つまり、最初に表示されるピクセルは、最初のバイトの最上位ビット。
トルエンディアンCPUの多バイトにまたがるシフト命令の方向と食い違っているのだ。
トルエンディアンのx86CPUで動く、WindowsAPIを使っているこの自分が、
まさかこんな仕打ちを受けることになるなんて、思ってもみなかった。
シフト命令を使っている以上、どうしようもないので、表示するときに直した。
ビットリバースには、こちら(No.493)の方法を使った。
幸い、何バイトでもまとめて実行できる形なので、さほどの負荷にはならなさそうだ。

*1:どうもこのタスクマネージャの数字は嘘っぽい。実際には13%程度か。ミリ秒単位で処理を返してSleepに入るようなものは検出できないのだろうか?