Speed calculator for LUA script

Origin : piece-me.org

File :

Source code :

Lua programming language 5.3.0 :

Original description :

年始頃に、「Lua 5.3.0」がリリースされていました。
Lua 5.3.0の新しい機能の中で、特に注目するのは、整数演算が対応されたことです。

Lua 5.2.xまでのLuaは、標準設定では、数値の内部処理が全て実数演算で処理されていました。
一見遅そうですが、実際には極端に遅い事も無く、良い割り切り方だと思っていました。確かAwkとかもそうですよね。

そんなわけで、実数演算のままでもさほど困らないのですが、Lua 5.3.0では整数演算が対応されました。
整数同士の演算ならば整数で処理するという動作で、普通のプログラム言語に近くなった感じです。

尚、Lua 5.3.0では、整数同士の演算でも、除算(/)だけは常に実数で処理されます。VBAと同じ感じですね。
「Lua 5.2.xとLua 5.3.0とで、同じ式を書いても結果が違う」というような非互換性は、無さそうです。
内部処理が整数か実数かの違いも、あまり気にしなくて良さそうです。(多分です…今後使って検証しようと思います。)

整数同士の演算が整数演算になったということで、高速化が期待できます。
というわけで、また速度計測を行ってみました。
計測条件の詳細は、前回(2012年2月8日)の記事を参照してください。今回は全て、高速RAM使用,48MHz駆動で計測しました。

結果はこうなりました。

結果[個]時間[ms]
C(int)168175
C(flt)168991
C(dbl)1683978
Lua1685232

まず、前回の結果に較べて、C(int)の結果が少し早くなっていますが、これはLuaとは関係ありません。
前回の計測から二年間の間に、自作の整数除算ルーチンを少し高速化した事が効いたのだと思います。

C(int)は置いといて、Luaの速度も早くなっています。前回の結果に較べて、約23%の高速化です。
しかし、実数演算を整数演算に置き換えたにしては、意外と高速化の効果が小さいです。
効果が小さい理由は、Lua 5.3.0の整数演算が、64ビット整数(long long)だからです。
P/ECEのCPU S1C33209は、32ビットCPUで、64ビット整数演算の命令は持っていません。
64ビット整数演算は、ライブラリ関数を呼び出してソフトウェアで処理する事になり、整数演算とはいえあまり早くありません。
実は今回の計測結果は、64ビット整数演算も高速RAMに配置して実行したのですが、それでも結構足を引っ張っているみたいです。

Lua 5.3.0の標準設定では、実数演算はdouble,整数演算はlong longで処理されます。
コンパイル時に特定のシンボルを定義しておくと、実数演算と整数演算の型を変える事も出来ます。
シンボル「LUA_USE_C89」を定義しておくと、実数演算はdouble,整数演算はintで処理されます。
シンボル「LUA_32BITS」を定義しておくと、実数演算はfloat,整数演算はintで処理されます。
これらの設定でも、速度計測してみました。

結果はこうなりました。

結果[個]時間[ms]
C(int)168175
C(flt)168991
C(dbl)1683978
Lua1683253
結果[個]時間[ms]
C(int)168175
C(flt)168991
C(dbl)1683978
Lua1682990

前回の結果に較べて、LUA_USE_C89は52%の高速化、LUA_32BITSは56%の高速化になりました。

ところで、LUA_USE_C89とLUA_32BITSで速度が違うのはなぜでしょうか。
整数演算は、どちらもintで行われるので、違いは無いはずです。
『2~1000の範囲にある素数の数』を求めるスクリプトには、一見、実数演算になる箇所も無さそうです。
しかし良く見ると、剰余演算(%)が有り、この箇所が実数演算で処理されるのだと思います。
LUA_USE_C89ではdouble,LUA_32BITSではfloatで処理され、その違いが速度差になるのだと思いました。

P/ECEとS1C33209のような、組み込み用32ビットマイコンでは、きっと、LUA_32BITSで使うのが適切なのでしょうね。
ゲーム用途ならば、実数演算はfloat,整数演算はintで大丈夫そうです。(floatはちょっと心許ない場合も有りますが…)
でもまずは、Lua 5.3.0の標準設定のまま、実数演算はdouble,整数演算はlong longで使ってみようと思います。
これまでlong longを多用することは無かったので、64ビット整数演算ルーチンの動作検証をする良い機会です。