Ruby Enterpriseの高速化案
authorNariさんのページで私が書いたコメントで、ワーキングセットが小さくなると書いてしまったのですが、小さくならないです。ビットマップ領域分まるまる大きくなりますね。大ボケなことをしてしまいました。autorNariさん、ページを汚して申し訳ありません。
くよくよしてもしょうがないので、新しい意見を書いてさらに大ボケをかますリスクをとります。
おなじみ(か?)の、オブジェクトがどこのヒープにあるか探すRuby Enterpriseのコードですが、
static inline struct heaps_slot * find_heap_slot_for_object(RVALUE *object) { register int i; /* Look in the cache first. */ if (last_heap != NULL && object >= last_heap->slot && object < last_heap->slotlimit) { /* 今までと同じヒープ領域をマーク (1) */ return last_heap; } /* 今までと違う領域をマーク (2) */ for (i = 0; i < heaps_used; i++) { struct heaps_slot *heap = &heaps[i]; if (object >= heap->slot && object < heap->slotlimit) { /* Cache this result. According to empirical evidence, the chance is * high that the next lookup will be for the same heap slot. */ last_heap = heap; return heap; } } return NULL; }
(2)の部分を通る場合、変数objectはキャッシュに載っていない可能性が高いと思われます。それは、今までマークしていたヒープ領域と違うヒープ領域になるからです。そこで、(2)の部分にprefetch命令を追加してobjectのアドレスでプリフェッチしておくとどうかなと思いました。そうすれば、objectをデリファレンスするときにはキャッシュに載っていて高速化できるんじゃないかなと思うのですが・・・。
試してみたいのですが、僕にはX86系の知識が無い、gccに伝える腕も無い(__asm__とか)ということで、今調べています。