MSX-DOS上でのGAME言語のベンチマーク [MSX]
「MSX-DOSに自作スクリーンエディタ移植」の記事内で書いたWebMSX環境を使ったMSX-DOSでGAME言語を動かした際のサンプルプログラムではGAMEコンパイラの効果があまり出ていなかったので実用的なプログラムに近いもので実行速度を評価してみました。
WebMSXでは「MSX2+ JAPAN(NTSC)」を選択し、QuickOptionsの設定内にある「CPU Turbo」を「8x」に設定しています。
使用したプログラムはインタプリタでの実行時間が数分かかりそうなものということで縦横合計式のクイズ(私が適当に作ったもの)を全探索で解くプログラムにしました。
A-Fは1~6の範囲の整数です。
ベンチマークで使われるASCIIARTの整数版と言ったところです。
参考にtwitterにポストした動画付きコメントを貼っておきます。
計測結果は次のとおりです。
尚、後述のようにBASICソースの先頭に「DEFINT A-Z」を追加したので上記のTwitterの値より速くなっています。
★2022/02/21 追記
自作のMC68Kボード(Pic24MC68K)を追記
DEFINTには対応していないのでREMでコメントアウトして実行
★2021/10/15 追記
自作のZ80ボード(Z80GAL)を追記
★2020/09/25 追記
自作のCP/M-86ボード(Pic24V20)が16MHzで動くようになったので追記
★2020/01/28 追記
パピコン(PC-6001)にGAMEインタプリタとコンパイラを移植したので追記
クロックが約4MHzにしては遅い結果でした。VRAMのDMA等が原因?
★2020/01/18 追記
PC-G850V(ポケコン)での内蔵C言語の測定結果を追記
BASICの4倍強、GAMEインタプリタより若干速いという結果でした。
★2020/01/16 変更
PC-G850V(ポケコン)でのGAMEインタプリタをチューニングし高速化
★2020/01/15 追記
PC-G850V(ポケコン)にGAMEコンパイラを移植したので測定結果を追記
インタプリタではかなり遅かったが、コンパイルするとクロック相当の速度
★2020/01/14 追記
PC-G850V(ポケコン)にGAME80を移植したので測定結果を追記
予想外に遅いですね^^;キーセンスのシステムコールで時間が掛かっている?
★2020/01/09 追記
PC-G850V(ポケコン)の測定結果を追記。エラー対処のため、下記の変更を実施
「DEFINT A-Z」 --> comment out
for段数超過エラーのため、変数Aに関してはIF文でループ
★2020/01/09 追記
CP/M-80でのGAME80 Interpreterの測定結果を追記
★2020/01/09 追記
CP/M-68KのCBASIC(Compiler)の測定結果を追記。コンパイルエラー対応のため、下記の変更を実施
「'」 --> 「REM」
「DEFINT A-Z」 --> comment out
「END」 --> 「STOP」
※コンパイラなのにメチャ遅いですねぇ^^;;
★2019/12/31 修正
BASICソースのfor文の初期値を0から1への修正に伴いBASIC系の実行時間を修正(なんとMSX BASICがGAME80より高速になった!)
CP/M-86のMBASICが異様に遅いのが気になりますが、CPUがV20(i8088互換)なので8bitバスであることが一因かもしれません。
尚、今回のベンチマークで使用したソースは次のとおりです。
★2019/01/08 変更
終了時のメッセージからスペースを削除し、GAME言語側と合わせた
★2019/12/31 修正
for文の初期値を0から1に修正
★2020/01/05 変更
行番号をGAME言語側ソースに合わせた(実行時間計測値は変化無し)
★2020/01/18 追加
★2019/12/31 修正
for文の初期値を0から1に修正
WebMSXでは「MSX2+ JAPAN(NTSC)」を選択し、QuickOptionsの設定内にある「CPU Turbo」を「8x」に設定しています。
使用したプログラムはインタプリタでの実行時間が数分かかりそうなものということで縦横合計式のクイズ(私が適当に作ったもの)を全探索で解くプログラムにしました。
A-Fは1~6の範囲の整数です。
ベンチマークで使われるASCIIARTの整数版と言ったところです。
ベンチマーク用のクイズ |
|
参考にtwitterにポストした動画付きコメントを貼っておきます。
WebMSX(MSX2JPN:8倍速)上のMSXDOSで
— skyriver (@wcinp) December 30, 2019
B+B+F=E
E+A+C=12
B+D+F=9
9 12 E
の縦横合計(A..Fは1..6)を解くAPでGAME言語を評価した
インタプリタでは54秒、コンパイル後1秒、MSX BASICでは132秒だった
参考にpicleコンパイラ(PIC24FJ:32MHz)ではコンパイル時間も含めて0.5秒程度#WebMSX #GAME #picle pic.twitter.com/lTug7yZi13
計測結果は次のとおりです。
尚、後述のようにBASICソースの先頭に「DEFINT A-Z」を追加したので上記のTwitterの値より速くなっています。
Language | Time[sec] | Environment |
---|---|---|
GAME80 Interpreter | 54 | WebMSX MSX2+ JAPAN, CPU Turbo 8x, MSX-DOS Ver1.03 |
GAME80 Compiler | 1 | WebMSX MSX2+ JAPAN, CPU Turbo 8x, MSX-DOS Ver1.03 |
MSX BASIC | 38 | WebMSX MSX2+ JAPAN, CPU Turbo 8x, BASIC Ver3.0 |
CP/M-80 GAME80 Interpreter | 52 | Pic24CPM ボード Z-80:16MHz |
CP/M-80 GAME80 V0.03 Interpreter | 43 | Z80GAL ボード Z-80:20MHz |
CP/M-80 GAME80 Compiler | 1 | Z80GAL ボード Z-80:20MHz |
CP/M-80 MBASIC | 65(1m5s) | Pic24CPM ボード Z-80:16MHz, MBASIC Rev. 5.21 |
CP/M-86 MBASIC | 191(3m11s) | Pic24V20 ボード V20:8MHz, MBASIC Rev. 5.22 |
CP/M-86 MBASIC | 97(1m37s) | Pic24V20 ボード V20:16MHz, MBASIC Rev. 5.22 |
CP/M-86 BASIC | 85(1m25s) | Pic24V20 ボード V20:16MHz, Personal Basic Ver 1.1 |
CP/M-68K CBASIC Compiler | 319(5m19s) | Pic24CPM68K ボード MC68008:8MHz, CBASIC Ver 1.0 |
PC-G850V BASIC | 296(4m56s) | PC-G850V(ポケコン) Built-in BASIC Interpreter Z-80:8MHz |
PC-G850V GAME80 Interpreter | 87(1m27s) | PC-G850V(ポケコン) Z-80:8MHz |
PC-G850V GAME80 Compiler | 2.5 | PC-G850V(ポケコン) Z-80:8MHz |
PC-G850V C Compiler | 72(1m12s) | PC-G850V(ポケコン) Built-in C compiler Z-80:8MHz |
PC-6001 GAME80 Interpreter | 395(6m35s) | PC-6001エミュレータ(PC6001V) PC-6001's CPU is Z80:3.9936MHz |
PC-6001 GAME80 Compiler | 11 | PC-6001エミュレータ(PC6001V) PC-6001's CPU is Z80:3.9936MHz |
ehBASIC V3.52 interpreter for 68000 | 67(1m7s) | Pic24MC68K(CP/M-68K) MC68HC000-P16:16MHz |
★2022/02/21 追記
自作のMC68Kボード(Pic24MC68K)を追記
DEFINTには対応していないのでREMでコメントアウトして実行
★2021/10/15 追記
自作のZ80ボード(Z80GAL)を追記
★2020/09/25 追記
自作のCP/M-86ボード(Pic24V20)が16MHzで動くようになったので追記
★2020/01/28 追記
パピコン(PC-6001)にGAMEインタプリタとコンパイラを移植したので追記
クロックが約4MHzにしては遅い結果でした。VRAMのDMA等が原因?
★2020/01/18 追記
PC-G850V(ポケコン)での内蔵C言語の測定結果を追記
BASICの4倍強、GAMEインタプリタより若干速いという結果でした。
★2020/01/16 変更
PC-G850V(ポケコン)でのGAMEインタプリタをチューニングし高速化
★2020/01/15 追記
PC-G850V(ポケコン)にGAMEコンパイラを移植したので測定結果を追記
インタプリタではかなり遅かったが、コンパイルするとクロック相当の速度
★2020/01/14 追記
PC-G850V(ポケコン)にGAME80を移植したので測定結果を追記
予想外に遅いですね^^;キーセンスのシステムコールで時間が掛かっている?
★2020/01/09 追記
PC-G850V(ポケコン)の測定結果を追記。エラー対処のため、下記の変更を実施
「DEFINT A-Z」 --> comment out
for段数超過エラーのため、変数Aに関してはIF文でループ
★2020/01/09 追記
CP/M-80でのGAME80 Interpreterの測定結果を追記
★2020/01/09 追記
CP/M-68KのCBASIC(Compiler)の測定結果を追記。コンパイルエラー対応のため、下記の変更を実施
「'」 --> 「REM」
「DEFINT A-Z」 --> comment out
「END」 --> 「STOP」
※コンパイラなのにメチャ遅いですねぇ^^;;
★2019/12/31 修正
BASICソースのfor文の初期値を0から1への修正に伴いBASIC系の実行時間を修正(なんとMSX BASICがGAME80より高速になった!)
CP/M-86のMBASICが異様に遅いのが気になりますが、CPUがV20(i8088互換)なので8bitバスであることが一因かもしれません。
尚、今回のベンチマークで使用したソースは次のとおりです。
1' quiz solver 1000 A=1,6 1005 / ?=A 1010 B=1,6 1020 C=1,6 1030 D=1,6 1040 E=1,6 1050 F=1,6 1060 !=2000 1070 @=F+1 1080 @=E+1 1090 @=D+1 1100 @=C+1 1110 @=B+1 1120 @=A+1 1130 /"complete!" 1140 #=-1 2000 ;=B+B+F<>E ] 2010 ;=A+C+E<>12 ] 2020 ;=B+D+F<>9 ] 2030 ;=B+E+B<>9 ] 2040 ;=A+B+D<>12 ] 2050 ;=C+F+F<>E ] 2060 /"A B C D E F =" 2070 ?(2)=A ?(2)=B ?(2)=C ?(2)=D ?(2)=E ?(2)=F 2080 ] |
1 ' quiz solver 1000 DEFINT A-Z 1010 FOR A=1 TO 6 1015 PRINT A 1020 FOR B=1 TO 6 1030 FOR C=1 TO 6 1040 FOR D=1 TO 6 1050 FOR E=1 TO 6 1060 FOR F=1 TO 6 1070 GOSUB 2000 1080 NEXT 1090 NEXT 1100 NEXT 1110 NEXT 1120 NEXT 1130 NEXT 1140 PRINT "complete!" 1150 END 2000 IF B+B+F<>E THEN RETURN 2010 IF A+C+E<>12 THEN RETURN 2020 IF B+D+F<>9 THEN RETURN 2030 IF B+E+B<>9 THEN RETURN 2040 IF A+B+D<>12 THEN RETURN 2050 IF C+F+F<>E THEN RETURN 2060 PRINT "A B C D E F ="; 2070 PRINT A;B;C;D;E;F 2080 RETURN |
★2019/01/08 変更
終了時のメッセージからスペースを削除し、GAME言語側と合わせた
★2019/12/31 修正
for文の初期値を0から1に修正
★2020/01/05 変更
行番号をGAME言語側ソースに合わせた(実行時間計測値は変化無し)
/* quiz solver */ int a,b,c,d,e,f; Check() { if ((b+b+f)!=e) return; if ((a+c+e)!=12) return; if ((b+d+f)!=9) return; if ((b+e+b)!=9) return; if ((a+b+d)!=12) return; if ((c+f+f)!=e) return; printf( "\nA B C D E F = %d %d %d %d %d %d",a,b,c,d,e,f ); } main() { for (a=1; a<7; a++ ) { printf( "\n%d",a ); for ( b=1; b<7; b++ ) { for ( c=1; c<7; c++ ) { for ( d=1; d<7; d++ ) { for ( e=1; e<7; e++ ) { for ( f=1; f<7; f++ ) { Check(); } } } } } } printf( "\ncomplete!" ); } |
★2020/01/18 追加
# quiz solver var a,b,c,d,e,f; proc Check() { if ((b+b+f)=e) { if ((a+c+e)=12) { if ((b+d+f)=9) { if ((b+e+b)=9) { if ((a+b+d)=12) { if ((c+f+f)=e) { PrnStr_( "\nA B C D E F =" ); PrnDecF_( a, 2 ); PrnDecF_( b, 2 ); PrnDecF_( c, 2 ); PrnDecF_( d, 2 ); PrnDecF_( e, 2 ); PrnDecF_( f, 2 ); } } } } } } } proc main() { for (a=1; a<7; a=a+1 ) { PrnStr_( "\n" ); PrnDec_( a ); for ( b=1; b<7; b=b+1 ) { for ( c=1; c<7; c=c+1 ) { for ( d=1; d<7; d=d+1 ) { for ( e=1; e<7; e=e+1 ) { for ( f=1; f<7; f=f+1 ) { Check(); } } } } } } PrnStr_( "\ncomplete!" ); } |
★2019/12/31 修正
for文の初期値を0から1に修正
レトロマイコン86ボードの構想(その18)asciiartの高速化 [8086]
V20(8088互換)を使った自作ボードで動作しているCP/M-86上でMBASICを使ってasciiartを動かしてみると3分18秒2分43秒(V20は8MHzで動作)で、Z-80でのASCIIARTの実行速度と比べてそれほど速いという感じはありませんでした(FPUを付ければ速くなるのだろうけど)
★2019/12/21 asciiart実行時間を修正(3分18秒はCP/M-80エミュでの時間でした^^;)
コンパイルすることである程度は高速化できるでしょうがどれだけ高速になるかはコンパイラに依存する部分が多々あります。
近年のコンパイラではコンパイル時の最適化として定数畳み込みやループ展開等の手法により、例えば最適化の結果、1~10の総和を求めるループ処理自体が単なる定数値になってしまうケースもあります。
それならば・・・と言うことでハンド最適化してみました(うそ)。
まず、asciiartの元ソースは下記でマンデルブロ集合での発散までの回数により表示コードを決定しています。
定数畳み込みとループ展開を手動で適用した結果、事前に計算できる結果を埋め込むことでV20の8MHz動作でasciiartの実行時間が33秒になりましたww
Twitterにポストした動画を貼っておきます。
種明かしは・・・
★追記 2023/01/24
「GAME言語での ASCIIART の高速化」の記事にアセンブラで書いた固定小数点を使い、asciiartを実際に高速化した内容を書きました。
[TOP] [ 前へ ] 連載記事 [ 次へ ]
★2019/12/21 asciiart実行時間を修正(3分18秒はCP/M-80エミュでの時間でした^^;)
コンパイルすることである程度は高速化できるでしょうがどれだけ高速になるかはコンパイラに依存する部分が多々あります。
近年のコンパイラではコンパイル時の最適化として定数畳み込みやループ展開等の手法により、例えば最適化の結果、1~10の総和を求めるループ処理自体が単なる定数値になってしまうケースもあります。
それならば・・・と言うことでハンド最適化してみました(うそ)。
まず、asciiartの元ソースは下記でマンデルブロ集合での発散までの回数により表示コードを決定しています。
10 FOR Y=-12 TO 12 20 FOR X=-39 TO 39 30 CA=X*.0458 40 CB= Y*.08333 50 A=CA 60 B=CB 70 FOR I=0 TO 15 80 T=A*A-B*B+CA 90 B=2*A*B+CB 100 A=T 110 IF (A*A+B*B)>4 THEN GOTO 200 120 NEXT I 130 PRINT " "; 140 GOTO 210 200 IF I>9 THEN I=I+7 205 PRINT CHR$(48+I); 210 NEXT X 220 PRINT 230 NEXT Y |
定数畳み込みとループ展開を手動で適用した結果、事前に計算できる結果を埋め込むことでV20の8MHz動作でasciiartの実行時間が33秒になりましたww
Twitterにポストした動画を貼っておきます。
V20(8088互換)を使った自作ボードでCP/M-86でMBASICでasciiartを動かしてみると3分18秒(V20は8MHz)でそれほど速いという感覚はありませでした。
— skyriver (@wcinp) December 20, 2019
ハンド最適化によりasciiartの実行時間が33秒になったよw(うそ)#ASCIIART #MBASIC #CPM86 #Pic24V20 #i8088https://t.co/FxIPabtDRw pic.twitter.com/yRV1VRSBz9
種明かしは・・・
10 DIM D$(20) 20 IDX=-1 30 IDX=IDX+1 40 READ D$(IDX) 50 IF D$(IDX)<>"" THEN 30 60 IDX=IDX-1 70 ST=0:EN=IDX:STP=1:GOSUB 500 80 ST=IDX-1:EN=0:STP=-1:GOSUB 500 90 END 500 FOR I=ST TO EN STEP STP 510 DSP$=D$(I):GOSUB 600 520 NEXT I 530 RETURN 600 L=LEN(DSP$) 610 FOR J=1 TO L 620 FOR T=0 TO ((L/2-ABS(J-L/2))/20)^5:NEXT T 630 PRINT MID$(DSP$,J,1); 640 NEXT J 650 PRINT 660 RETURN 1000 DATA "000000011111111111111111122222233347E7AB322222111100000000000000000000000000000" 1010 DATA "000001111111111111111122222222333557BF75433222211111000000000000000000000000000" 1020 DATA "000111111111111111112222222233445C 643332222111110000000000000000000000000" 1030 DATA "011111111111111111222222233444556C 654433332211111100000000000000000000000" 1040 DATA "11111111111111112222233346 D978 BCF DF9 6556F4221111110000000000000000000000" 1050 DATA "111111111111122223333334469 D 6322111111000000000000000000000" 1060 DATA "1111111111222333333334457DB 85332111111100000000000000000000" 1070 DATA "11111122234B744444455556A 96532211111110000000000000000000" 1080 DATA "122222233347BAA7AB776679 A32211111110000000000000000000" 1090 DATA "2222233334567 9A A532221111111000000000000000000" 1100 DATA "222333346679 9432221111111000000000000000000" 1110 DATA "234445568 F B5432221111111000000000000000000" 1120 DATA " 864332221111111000000000000000000" 1130 DATA "" |
★追記 2023/01/24
「GAME言語での ASCIIART の高速化」の記事にアセンブラで書いた固定小数点を使い、asciiartを実際に高速化した内容を書きました。
[TOP] [ 前へ ] 連載記事 [ 次へ ]
MSX-DOSに自作スクリーンエディタ移植 [MSX]
MSX-DOSはCP/M-80のDOSコールサービスに対応しているのでCP/M-80用の多くのソフトが動作します。
試しに「3チップ構成Pic24CPMマイコン(その7)GAMEコンパイラ」の記事で書いたGAME言語で試してみたところ、インタプリタ及びコンパイラが問題なく動作しました。
実機のMSXマシンが無いので動作環境としてはWebMSXを使わせていただきました。
※WebMSX環境ではALT+V操作でコピペ可能です。
GAME言語を使ってMSX-DOSのメモリを確認した結果、MSX-DOSではRST28を使っていないようでした。
CP/M-80用ディバッガのZSIDで使っているRST38をRST28に変更することでMSX-DOS上で動作しました。
ZSIDはダンプ表示1行化のパッチと「3チップ構成Pic24CPMマイコン(その4)ZSIDで小文字のシンボルを使う方法その2」の記事で書いた小文字シンボル対応のパッチを入れ、コマンド名と表示名をZSIDM(MSX用なので'M'を追加)にしました。
また、CP/M-80用のHI-TECH Cを試してみたところ問題なく動作しました。
注意点として、Bドライブに入れましたがBドライブもbootableにしないと動作後にMSX-DOSのコマンド入力状態に戻れなくなります。
CP/M-68K用に開発し、CP/M-80にも移植した自作スクリーンエディタ(sked)をMSX-DOSに移植を試みました。
MSX-DOSのエスケープシーケンスについてはMSX Datapack wiki化計画の14章 画面制御コードを参照させていただきました。
MSX-DOSには反転表示や色付き等に表示文字属性を変更するエスケープシーケンスが無いのでステータス行の区別が付きづらいため、25行目をステータス行に固定し、ファイル内容は24行表示にしてみました。
また、skedでは改ページ(^L)等の制御コードを色付きで表示していましたが、色付きができないので色なしで表示するようにしています。
画面モードは80文字x25行を想定していますのでMSX-DOSの「mode 80」のコマンドで画面モードを変更してから起動しています。
MSX-DOS用のskedは下記からダウンロードできます。商用利用以外であれば自由に使用可能です。
また、MSX-DOSでも動作するzsidも置いておきます。
試しに「3チップ構成Pic24CPMマイコン(その7)GAMEコンパイラ」の記事で書いたGAME言語で試してみたところ、インタプリタ及びコンパイラが問題なく動作しました。
実機のMSXマシンが無いので動作環境としてはWebMSXを使わせていただきました。
※WebMSX環境ではALT+V操作でコピペ可能です。
CP/M-80に移植したGAME言語をWebMSXで動かしてみた
— skyriver (@wcinp) December 1, 2019
コンパイラも動いたけどソースをコピペができないのでソースのロード/セーブ機能を追加しないと使いづらい・・#GAME言語 #GAMEコンパイラ #MSXDOS #WebMSXhttps://t.co/7OsMhjhhbX pic.twitter.com/e3KTLJSHks
GAME言語を使ってMSX-DOSのメモリを確認した結果、MSX-DOSではRST28を使っていないようでした。
MSX-DOSのGAME言語によるメモリダンプ |
|
CP/M-80用ディバッガのZSIDで使っているRST38をRST28に変更することでMSX-DOS上で動作しました。
ZSIDはダンプ表示1行化のパッチと「3チップ構成Pic24CPMマイコン(その4)ZSIDで小文字のシンボルを使う方法その2」の記事で書いた小文字シンボル対応のパッチを入れ、コマンド名と表示名をZSIDM(MSX用なので'M'を追加)にしました。
MSX-DOS上で動作中のZSID |
|
また、CP/M-80用のHI-TECH Cを試してみたところ問題なく動作しました。
注意点として、Bドライブに入れましたがBドライブもbootableにしないと動作後にMSX-DOSのコマンド入力状態に戻れなくなります。
MSX-DOS上で動作中のHI-TECHC |
|
CP/M-68K用に開発し、CP/M-80にも移植した自作スクリーンエディタ(sked)をMSX-DOSに移植を試みました。
MSX-DOSのエスケープシーケンスについてはMSX Datapack wiki化計画の14章 画面制御コードを参照させていただきました。
MSX-DOSには反転表示や色付き等に表示文字属性を変更するエスケープシーケンスが無いのでステータス行の区別が付きづらいため、25行目をステータス行に固定し、ファイル内容は24行表示にしてみました。
また、skedでは改ページ(^L)等の制御コードを色付きで表示していましたが、色付きができないので色なしで表示するようにしています。
画面モードは80文字x25行を想定していますのでMSX-DOSの「mode 80」のコマンドで画面モードを変更してから起動しています。
MSX-DOS上でのsked |
|
MSX-DOS用のskedは下記からダウンロードできます。商用利用以外であれば自由に使用可能です。
- SKED_MSX_20191209.zip
★2019/12/09 変更 ステータス表示部効率化
また、MSX-DOSでも動作するzsidも置いておきます。