読者です 読者をやめる 読者になる 読者になる

プチコンで遊ぼう! (はてなブログ版)

任天堂3DSのプチコンで遊ぼう! [twitter:@eida_s]

はてなダイアリーから移行しました。 はてなダイアリーのURLを開いても自動的にこちらにリダイレクトされますのでご了承ください。

補足: ほしけんさんのプチコン漢字ライブラリの高速化を試みた

「ほしけんさんのプチコン漢字ライブラリの高速化を試みた」のエントリの補足(兼自分用メモ)。
eidaht.hatenablog.com

「ほしけんさんのプチコン漢字ライブラリの高速化を試みた」でキャッシュなどを導入してプチコン漢字ライブラリの高速化を行いましたが、いくつか注意点と今後の改良点を。
改造版プチコン漢字ライブラリを以後はKNJLIB_MOD1と表記します。


■注意点1.KNJLIB_MOD1ではメモリ使用量に注意が必要

オリジナル版ではプログラム内リソースを使っているので、ライブラリがロードできればメモリが足りなくなる、ということはないように考えられています。
しかし、KNJLIB_MOD1では参照表に512キロバイトほどの配列を使い、さらにキャッシュ用として動的に拡張する配列を使います。
(キャッシュ用は、16x16フォントでキャッシュサイズが初期状態の300文字の場合、300キロバイト)。

つまり、オリジナル版は、使う側はライブラリの中身をよくしらなくてもブラックボックスとして使えるように設計されていますが、
KNJLIB_MOD1の方は使用するメモリ量を意識しておく必要があります。
(もちろんほとんどケースでは何も考えなくてもメモリが不足することはないと思いますが...。)

さもないと、単純にオリジナル版を置き換えたらメモリ不足で止まってしまった、ということが起こりえます。


■注意点2.パフォーマンス重視の場合、キャッシュを最適化する

KNJLIB_MOD1でパフォーマンス重視の設定にしたい場合は、キャッシュを最適化した方がよいです。
キャッシュは、決められたキャッシュサイズがあり、キャッシュサイズ一杯の状態で新たな文字を読み込むと、最も長く使われていなかった文字をキャッシュから追い出して新たな文字を追加します(いわゆるLRU法)。
この追い出しが発生すると処理に時間がかかってしまいます。
また、キャッシュされている文字がいつ使われたかを覚えておくための領域があり、キャッシュが使われるたびにこれを更新するので、ここでも若干の時間がかかります。
これらのことから、最もパフォーマンスを発揮できるのは、プログラム内で使う文字をすべてキャッシュに収め、かつ、使った文字を覚えておく機能をオフにした時です。

これをできるように、設定用のCOMMON DEFを追加してあります。

・GKNJCACHESIZE
 使い方: 変数 = GKNJCACHESIZE(キャッシュサイズ)
 キャッシュサイズを設定します。
 キャッシュサイズの変更は随時可能ですが、すでに使っているキャッシュサイズよりも小さな値を設定しても、実際のキャッシュサイズは縮小しません。
 キャッシュサイズは、キャッシュに納める文字数を設定します。戻り値はキャッシュサイズを返します。
 キャッシュサイズをプログラムで使う全ての文字の種類より大きく設定するとキャッシュ追い出しが発生しないので、最もパフォーマンスを得ることができます。
 なお、キャッシュに使うメモリ使用量は、(フォント幅×フォント高さ×4×キャッシュサイズ)で計算できます。
 例えば、16x16ドットフォントでキャッシュサイズが300文字の場合、16×16×4×300=307200バイト=300キロバイトを使用します。

・GKNJCACHELRU
 使い方: 変数 = GKNJCACHELRU(TRUE または FALSE)
 使った文字を覚えておく機能のオン・オフを設定します。TRUEでオン、FALSEでオフとなります。
 使った文字を覚えておく機能をオンにしておくと、キャッシュを使うごとにLRUキューの先頭に使った文字を移動します。
 オフの場合、LRUキューの先頭への移動は起こりません。
 LRUキューがキャッシュサイズに達している時に、新たな文字がキャッシュに追加されようとすると、LRUキューの末尾の文字をキャッシュから追い出します。
 前述のキャッシュサイズを最適化して、キャッシュの追い出しが発生しないようにした場合、オフにしておくと若干速度が向上します。
 
!!! とここまで書いて、GKNJCACHELRUにバグがあることがわかりましたので後で直します。スミマセン。 !!!



■注意点3.フォントを切り替えているケースではかえって遅くなる場合がある

KNJLIB_MOD1では、キャッシュがフォントの切り替えに対応しておらず、フォントが切り替わった時に一旦すべてのキャッシュを捨てています。
また、構造上、キャッシュに入っていないフォントをキャッシュに追加するオーバーヘッドで若干時間がかかります。
このため、フォントを頻繁に切り替えている場合、キャッシュを捨てる処理と、フォントをキャッシュに追加するオーバーヘッドの分、オリジナル版より時間がかかることになります。
これに対する対策はフォントの切り替えを行わない、くらいしかありません。
ですが、これでは既存のプログラムに対応できないので、次の今後の改良点につながります。


■今後の改良点.キャッシュをフォント切り替えに対応する

上記注意点3に関する問題は、キャッシュ自体をフォントの数だけ持っておき、それを切り替えることで理論上対応可能です(さらにメモリ消費しますが...)。
そこで次のバージョンではフォント切り替えに対応したキャッシュシステムへの拡張を行います。
さらにメモリを消費するようになるため、これで万事解決、ではないですがとりあえず。