39546行
jessやjackでどこがボトルネックになっているのかを調べるために、xprofilerをサポートした。SunのHotspotより10倍近く遅いのは、なんとしても原因を突き止めなければならない。
xprofilerはKaffeが提供している異言語間プロファイラである。基本的にはgprofに食わせるプロファイリング情報を吐いてくれるのだが、ネイティブの関数だけでなくJITコンパイラが吐いたJavaメソッドのコードに関するプロファイルもサポートしている。当然JITコンパイラがxprofilerをサポートする必要があるのだが、現状ではLinux or FreeBSD/i386でしかサポートされていない。そこでチョコチョコっとハックしてSolaris/SPARCのサポートを追加した。これは本家のKaffeにマージする価値がある仕事かもしれないが、ちょっと汚い作業が色々と必要なので面倒だ。
それはともかく、jessでプロファイルを取ってみた。環境はいつもと同じで、UltraSPARC III/40GB メモリ/Solaris 9でオプションは"-ms700m -mx700m"である。トップ15は以下のとおり。
Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 5.00 2.99 2.99 21825306 0.00 0.00 spec::benchmarks::_005f202_jess::jess::ValueVector::get(int) 4.70 5.80 2.81 addToCounter 4.60 8.55 2.75 _unlockMutex 4.40 11.18 2.63 finishGC 4.12 13.64 2.46 gc_heap_malloc 4.07 16.07 2.43 _lockMutex 3.83 18.36 2.29 jthread_enable_stop 3.48 20.44 2.08 jthread_disable_stop 3.38 22.46 2.02 objectStatsChange 3.36 24.47 2.01 profileArcHit 3.26 26.42 1.95 14197653 0.00 0.00 spec::benchmarks::_005f202_jess::jess::Value::equals(spec::benchmarks::_005f202_jess::jess::Value *) 3.23 28.35 1.93 gcMalloc 3.13 30.22 1.87 utf8ConstNew 3.08 32.06 1.84 gcMan 2.31 33.44 1.38 9440721 0.00 0.00 spec::benchmarks::_005f202_jess::jess::ValueVector::equals(java::lang::Object *)
1位のget()は単純なアクセスメソッドである。RJJはインライン展開をしていないので悲惨なことになっている。次のaddToCounter()は統計情報を取るためのVM内部の関数で、これは本当の性能測定の際にははずせる。
問題はそれ以降で、ロックとメモリ管理が多くを占めている。これらは残念ながら、JITコンパイラでは手出しのできない領域である。Kaffeのロックやメモリ管理まわりの何が問題なのかはわかっているのだが、さすがにそこまで直している時間はない。
原因はわかったのでしばらく放置することになろう。ロックはともかく、GCについてはヒープをもっと増やすことで対応できなくはないと思う。