- いろいろな改善を施す前に、まず現状を把握しておきましょう。あまり大きなプログラムで議論しても複雑で理解が困難になるので、app0016を題材にしたいと思います。
int32s i:R00, sum:R01, j:R02;
for (j = 1000000; j != 0; j--) {
sum = 0;
for (i = 10000; i != 0; i--) {
sum += i;
}
}
- osecpu034の段階では、このプログラムは102バイトになります(実行ファイルは4バイトのシグネチャがつくので106バイト)。102バイトってそんなに悪くないと思うかもしれませんが、これはとんでもなく悪いです。
0202000F4240 010000000000 020100000000 020000002710 010000000002
14010100 023F00000001 1500003F 023F00000000
213F003F 043F 030000000002 010000000003 023F00000001 1502023F
023F00000000 213F023F 043F 030000000000 010000000001
- 同じプログラムをx86の32bitで書いたとします。そうすると何バイトになるかというと、19バイトになります。
MOV EDX,1000000
label0:
XOR EAX,EAX
MOV ECX,10000
label1:
ADD EAX,ECX
LOOP label1
DEC EDX
JNZ label0
- 19バイトのダンプはこちらです。
BA40420F00 31C0 B910270000 01C8 E2FC 4A 75F2
- 102と19を比較すればその差は5.37倍。同じ機能を記述するためにこんなに違うのですから、OSECPUのアプリは機能密度がx86の5倍以上劣る、といえます。・・・これはひどいとうことがお分かりいただけましたか。
- 言い訳を書いておくと、ver.034までのOSECPUはアプリの機能密度をまともにするための努力を全くしていませんでした。しかし準備はしていました。その気になればいつでも機能密度が上げられるようにと、命令セットには隠れた工夫を入れていたのです。ついにその隠し玉を存分に使う日が来ました!
- ちなみに今のバイトコード体系はまさに内部処理向きに作ってあって、そのおかげで内部処理は書きやすくなり、10.5KBを実現していました。だからしわ寄せのせいでアプリが大きいという指摘は当たっています。
- 内部処理用のバイトコードは「バックエンドコード」と呼ばれるのが普通で、表に表れるバイトコードは「フロントエンドコード」と呼ばれます。x86でも、私たちが使っているのはフロントエンドコードで、内部ではRISC命令的なバックエンドコードがあるといわれています。しかし表に出てこないのでその仕様はほとんど分かりません。
- つまり何が言いたいのかというと、フロントエンドとバックエンドがあるというのは、普通の構成なのです。