gcc向け最適化をしてみた
gccで使えるテクニックの、スレッデッドコードというのが仮想マシンループにとても有効ということで、実装してみたのですが、
普通にswitch caseの方が早いんですが、これは…?
↓こんな感じで実装してます。
#ifdef __GNUC__ # define XTAL_VM_OPT #endif #ifdef XTAL_VM_OPT #define XTAL_VM_NODEFAULT } goto *label_table[*pc]; #define XTAL_VM_FIRST_CASE(key) Label##key: { #define XTAL_VM_CASE(key) } goto *label_table[*pc]; Label##key: { #define XTAL_VM_SWITCH(x) goto *label_table[x]; #else #define XTAL_VM_NODEFAULT } goto begin; #define XTAL_VM_FIRST_CASE(key) case Inst##key::NUMBER: { #define XTAL_VM_CASE(key) } goto begin; case Inst##key::NUMBER: { #define XTAL_VM_SWITCH(x) switch(x) #endif void VMachineImpl::execute_inner(const inst_t* start){ #ifdef XTAL_VM_OPT static void* label_table[] = { &&LabelNop, &&LabelPushNull, &&LabelPushNop, &&LabelPushTrue, &&LabelPushFalse, ... }; #else #endif begin: XTAL_VM_SWITCH(*pc){ XTAL_VM_FIRST_CASE(Nop){ pc += 命令サイズ; } XTAL_VM_CASE(PushNull){ push(null); pc += 命令サイズ; } XTAL_VM_CASE(PushTrue){ push(true); pc += 命令サイズ; } XTAL_VM_CASE(PushFalse){ push(false); pc += 命令サイズ; } XTAL_VM_CASE(PushNop){ push(nop); pc += 命令サイズ; } ... XTAL_VM_NODEFAULT; }