SSブログ
English Version

ポケコン(PC-G850V)でGAME言語(その4)GAME高速化 [ポケコン]

 前回記事の「ポケコン(PC-G850V)でGAME言語(その3)GAMEコンパイラ」の最後の方に書いたように、ベンチマーク測定の結果、GAMEコンパイラはそれなりの速度ですがインタプリタはかなり遅い結果でした。

 気になったので原因を調査しました。結果、やはりキーセンス処理で時間が掛かっていたようです。

 今回のキーセンスセンス処理ではG850のIOCS(BIOS)処理であるリアルタイムキー入力(0BE53H)を使用しています。
 ネット情報ではIOCSのコールの中ではキーマトリックス回路にセンスビットを出力する度に0.2msのソフトタイマを実行しているようです。

 また、キー入力があった(Cy:1)場合に、Aレジスタで帰ってくるキーマトリックスデータを自前の処理でデコードし有効なキーが押されているか確認しています。この処理も通常のキー入力バッファ内のキャラクタ数を確認するような処理よりは重くなります(でもこの処理はキーが押されている間だけなので影響は少ない)。

 一方、GAMEインタプリタではキーセンス処理をコールするところが次の2ヶ所ありました。
  1. ソースのステートメント解析部
    予期せぬループ状態になった場合にBREAKできるように、ステートメントを解析する度にキーセンス処理をコールしている。
  2. 文字列出力部
    文字列出力後にキーセンス処理をコールしている。

 後者はあまり影響ないのですが、前者のコールは頻繁に発生するので前述のような今回の実装では実行速度に大きな影響が出ていました。
(因みにGAMEコンパイラは高速化のために後者だけコールしています)

 対策として上記 i のケースでのキーセンス処理を間引いてコールすることにしました。
 間引き数と実行時間の関係は下記の通りです。

No.コール比率ベンチマーク実行時間[sec]
1/1553(9m13s)
1/16113(1m53s)
1/3298(1m38s)
1/6491(1m31s)
1/12887(1m27s)
1/25685(1m25s)


 この結果から間引き率は1/64としました。

★2010/01/17 追記 {
 上表に1/128と1/256を追記。256ではブレークキー('TAB')の感度低下が感じられた。
 Ver0.02dで1/128に変更しました。
}

 今回高速化したGAME言語のインタプリタは「ポケコン(PC-G850V)でGAME言語」のページからダウンロードできます。

 今回の変更でバージョンを 0.02c としました。

 また、ベンチマーク結果は「MSX-DOS上でのGAME言語のベンチマーク」の記事にまとめています。

GAME言語起動画面


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

ポケコン(PC-G850V)でGAME言語(その3)GAMEコンパイラ [ポケコン]

 前回の「ポケコン(PC-G850V)でGAME言語(その2)」で書いたようにポケコン(G850V)環境でTEXTエディタで編集している内容をGAME言語のソースにコンバートするツールができたので今回はポケコンでGAMEコンパイラを動かしてみました。

 TK-80BS用のGAMEインタプリタは開始アドレスが 8600H ですが、ポケコン(G850)はメモリの後半が ROM なのでインタプリタの開始アドレスを 0400H に変更しています(インタプリタ本体及びワークエリアはそのまま平行移動)。

 従ってGAMEコンパイラを動かすためにはコンパイルの際、埋め込まれるインタプリタ内処理とワークエリアのアドレスを変更する必要があります。
 GAMEコンパイラのソースを眺めてみると $8xxx(xは[0-9,A-F])の部分を

0400H - 8600H

の値を加算したものに変更すれば動きそうです。

 手作業で変更するのは面倒なので変換ツールを作り、一括変換しました。
 変換時のログが下記になります。コンパイラソースの行カウント値、行番号、変更前データ、変更後データを表示しています。

GAMEコンパイラ内のインタプリタ関連アドレス変換ログ
C:\src\G850V\comp>perl cnvcomp.pl <GAMECOM.GAM >GAMEC.GAM

    7    65 : $8D06 -> $0B06
   15   220 : $8603 -> $0403
   15   220 : $8603 -> $0403
   25   380 : $8C83 -> $0A83
   31   440 : $8B58 -> $0958
   33   460 : $8B85 -> $0985
   34   470 : $8D52 -> $0B52
   75  2420 : $8785 -> $0585
   78  2510 : $8C26 -> $0A26
   80  2610 : $8C32 -> $0A32
   81  2620 : $8C31 -> $0A31
   83  2710 : $8C31 -> $0A31
   85  2810 : $8B9C -> $099C
   95  3210 : $8A03 -> $0803
   96  3220 : $8A0F -> $080F
   97  3230 : $8A2C -> $082C
  111  3610 : $8A03 -> $0803
  140  4620 : $889E -> $069E
  144  4720 : $8D4E -> $0B4E
  145  4750 : $8C96 -> $0A96
  148  4800 : $8A5B -> $085B
  149  4810 : $8872 -> $0672
  150  4820 : $8881 -> $0681
  151  4830 : $8904 -> $0704
  190  5740 : $8A03 -> $0803
C:\src\G850V\comp>


 このような処理はGAME言語では荷が重いのでperlを使いました。ソースは以下の通りで使い捨てツールなので凝った作りにはしていません。

GAMEコンパイラ内アドレス変換ツール(perl)
#!/usr/bin/perl # convert GAME compiler to any offset # ver 0.01 2010/01/15 skyriver use strict; use warnings; my $OrgStart = 0x8600; my $NewStart = 0x0400; # set here new start address my $Ofst = $NewStart - $OrgStart; my $LinCnt; # line counter my $LinNo; main(); sub main { my ($ln,$find,$change); while( <> ) { chomp(); $LinCnt++; $ln = $_; if( $ln =~ /^(\d+)/ ) { $LinNo = $1; while ( $ln =~ /\$(8[0-9,A-F]{3})/ ) { $find = $1; $change = eval( "0x" . $find ) + $Ofst; $change = sprintf( "%04X", $change ); printf( STDERR "\n%5d %5s : \$%s -> \$%s", $LinCnt, $LinNo, $find, $change ); $ln =~ s/\$$find/\$$change/; } printf( "%s\n", $ln ); } } }


★2020/01/16 追記 Twitterにポストしたメッセージを貼っておきます。


 「MSX-DOS上でのGAME言語のベンチマーク」の記事でベンチマークに今回のポケコンでのGAMEインタプリタとコンパイラの結果を追記しました。
 G850V(Z-80:8MHz)でのGAMEインタプリタは予想に反してかなり遅い結果で、同じコードが動いているPic24CPM ボード(Z-80:16MHz)のCP/M-80でのGAME80インタプリタの10倍程度遅いです。

 インタプリタ自体は同じコードなのでキーセンス処理が原因かと思い、キー入力チェック無しにリターンするようにしましたが変化はなく、現時点では原因不明です。

 今回移植したGAMEコンパイラの結果も追記していますが、コンパイラの方はクロック相応の速度が出ているようです。

 GAMEコンパイラを同梱したファイルは「ポケコン(PC-G850V)でGAME言語」のページで公開しています。

 GAMEコンパイラのソースを公開していいのか不明(GAME本体のソースも同様)なのでコンパイル後のHEXファイルのみ付けていますが、「3チップ構成Pic24CPMマイコン(その7)GAMEコンパイラ」の記事を参照すればGAMEコンパイラのソースを入手できます。


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー