LL魂2007(LLSpirit)のライトニングトークで発表したときに使ったデモのコード(Python+Xbyak)を公開します.
使い方は添付のreadme.txtを参照してください.
ベンチマーク結果をあげておきます.
ループ回数 | 実行時間(sec) | 処理時間比(Xを1とする) | ||
---|---|---|---|---|
Xbyak(可変) | 100000 | 12.14 | 1 | |
python(可変) | 100 | 10.73 | 894 | |
psyco(可変) | 1000 | 40.8 | 340 | |
python(固定) | 1000 | 42.55 | 354 | |
psyco(固定) | 10000 | 32.91 | 27.4 | |
C++(固定) | 100000 | 13.94 | 1.16 |
psycoはPythonのJIT実行環境です.Xbyakはこれの特別版と考えればよいでしょう.psycoは何もしなくても速くなりますが,Xbyakは全て自分でコードを書く必要があります.
今回のベンチマークの目的は,関数を文字列として与えられたときに,それを実行時に評価(eval)する速度比を測ることです.Xbyakやpython(可変), psyco(可変)がそれにあたります.
それに対して,evalがどれぐらい重いのかを見るために,同時に関数を文字列でなく本来の関数として定義した場合の速度も測りました.それがpython(固定)やpsyco(固定),およびC++(固定)で作ったものです.
見てのとおり,可変と固定のハンディをものともせずXbyakがトップです.実は100倍どころの速度比ではありません.通常最速と思われるC++(固定)よりも速かったのは意外です.ただし,これはXbyakでSSE2を使ったためと思われます(でないと勝てるわけがない).
またpsyco(固定)の速度向上も目を見張るものがあります.何もせずにこれだけ速くなるのはたいしたものです.
# Pythonのarrayが16byte alignmentしてくれればXbyak版ももっと速くできる*のですが….
なお,コードを見ればわかりますが,Xbyak版はかなり手抜き(100行程度だし)であること,また一般的に上記のような性能向上が常に得られるとは限りませんが,ピンポイントで効果的に使えればかなりの破壊力があることは分かると思います.
コード内容については後日簡単に説明する予定です.
*おまけ(毒を食らわば皿まで)
Python本体ソースのmalloc関数たちを_aigned_mallocに変更してリコンパイルし,xbyak側のメモリアクセスをalignmentされていないときでも動くmovupsからalignment前提のmovapsに変更すると12sec => 8.75secとなり,効果があることが分かりました.