簡単なレジスタベースVMを作り、fib(38)
を実行した時のマイクロベンチ結果
アドレスのアラインメントを利用した埋め込みを実装した処理系
オブジェクトは環境非依存で64bit固定
ポインタをmodifyする必要がある
多くの環境で64bitアドレスの上位16bitが使用可能であることを利用した埋め込みを実装した処理系
オブジェクトは環境非依存で64bit固定
ポインタはmodifyしなくて良い(上位16bitを見れば良いだけなので)
IEEE754のNaNの冗長性を利用した埋め込みを実装した処理系
64bitアドレスの埋め込みは上記の上位16bitが使用されていない事を利用している
そのためポインタはmodifyしなくて良い
また、上記の実装に加え、倍精度浮動小数が即値で扱える
上記のC++バージョン
Rustにunionが無いのと、transmute
がやたらコストかかるので比較のためのC++実装
Rustはver 0.10現在、Windows向けにx64対応がされていない
なので、x86はWindows、x64はUbuntuで各々比較
x86もx64もVC++(VS2013)で行った
基本演算はオペランドの符号情報を動的に扱うものとコンパイル時に決め打つものの2種類を用意
つまり、動的型付けバージョンと静的型付けバージョンのどちらも対応
オペランドの符号情報を動的に取得: 約8.1秒
オペランドの符号情報を静的に決定: 約5.6秒
オペランドの符号情報を動的に取得: 約5.0秒
オペランドの符号情報を静的に決定: 約3.5秒
オペランドの符号情報を動的に取得: 約9.11秒
オペランドの符号情報を静的に決定: 約5.5秒
オペランドの符号情報を動的に取得: 約5.1秒
オペランドの符号情報を静的に決定: 約3.6秒
どの環境でもめちゃくちゃ時間かかった
30秒とか平気にかかるレベル
オペランドの符号情報を動的に取得: 約3.1秒
オペランドの符号情報を静的に決定: 約3.1秒
オペランドの符号情報を動的に取得: 約4.8秒
オペランドの符号情報を静的に決定: 約4.7秒
-
RustでNaN boxing遅すぎる
Rustのtransmute
がかなり重いっぽい
Rustにはunionが無いのでビットレベルでの操作をどうしていいのかよくわからなくてとりあえずtransmute
つかいまくったらこのざま
何かしらのベストプラクティスがあるのかもしれない -
RustとC++でそこまでの速度は無いっぽい?
これならRustでVM書けそう
正直テンション上がる -
NaN boxing in C++で32bit環境の方が速くなった
謎
いや、本気で謎
あとC++でオペランドの符号情報の動的/静的取得に差が無いのも謎 -
C#(VS2013)でfib(38)試したら0.2秒だった
正直JITかけたらこのあたりの差なんて誤差レベルになるんじゃ?とか思わなくもない