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) 168 175 C(flt) 168 991 C(dbl) 168 3978 Lua 168 5232
まず、前回の結果に較べて、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) 168 175 C(flt) 168 991 C(dbl) 168 3978 Lua 168 3253
結果[個] 時間[ms] C(int) 168 175 C(flt) 168 991 C(dbl) 168 3978 Lua 168 2990
前回の結果に較べて、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ビット整数演算ルーチンの動作検証をする良い機会です。