-1
我想用C/C++构建一个快速的JIT。它应该将我的字节码转换为IA32。是的,我知道libjit和类似的,但我相信他们并不简单。我认为我已经找到了更快捷的方式来构建指令,但我错了 - 传统的开关/外壳方法比我的快两倍。我的方法是复制一个块,然后填写一个模板。我知道现代编译器上的switch/case会创建一个跳转表,所以我没有跳转表的实现。简单的字节码翻译器
我已经使用了一个包含循环到基准的代码[]的内容的50mb文件。 我的配置是:i7,8gb ram,使用VS2010编译。
这里是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
//unsigned char code[] = {1,2,3,4,4};
void mycopy(unsigned char* to, unsigned char* from, int size) {
int i = 0;
while(i < size) {
/*if (i < size-3) {
if (*(unsigned int*) &from[i] == 0xFFFFFFFF) {
*(unsigned int*) &to[i] = 0xC3C3C3C3;
i += 4;
continue;
}
}*/
to[i] = from[i];
i++;
}
}
void translateA(unsigned char* code, unsigned char* output, int size) {
unsigned char A[] = { 3, 1, 1, 1 }; // { size, <bytes...> }
unsigned char B[] = { 2, 2, 2 };
unsigned char C[] = { 8, 3, 3, 3, 3, 0xFF, 0xFF, 0xFF, 0xFF };
unsigned char D[] = { 1, 4 };
void* templat[] = { &A, &B, &C, &D };
int i = 0;
int total = 0;
while(i < size) {
int op_index = (int) code[i] - 1;
unsigned char* instr_buffer = (unsigned char*) templat[op_index];
int size = (int) instr_buffer[0];
instr_buffer++;
mycopy(output+total, instr_buffer,size);
total += size;
i++;
}
}
void translateB(unsigned char* code, unsigned char* output, int size) {
for(int i = 0; i < size; i++) {
switch(code[i]) {
case 1:
output[0] = 1;
output[1] = 1;
output[2] = 1;
output += 3;
break;
case 2:
output[0] = 2;
output[1] = 2;
output += 2;
break;
case 3:
output[0] = 3;
output[1] = 3;
output[2] = 3;
output[3] = 3;
output[4] = 0xC3;
output[5] = 0xC3;
output[6] = 0xC3;
output[7] = 0xC3;
output += 8;
break;
case 4:
output[0] = 4;
output++;
break;
}
}
}
int main(int argc, char* argv[]) {
// load the 'code' to an array
FILE* f = fopen("testops.bin", "r+");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
unsigned char* code = (unsigned char*) malloc(fsize);
fread(code, fsize, 1, f);
fclose(f);
unsigned char* output = (unsigned char*) malloc(fsize*10);
memset(output, 0x7A, fsize*10);
// benchmark it
time_t start = clock();
// Replace with translateB. It's ~2x faster
translateA(code, output, fsize);
printf("\nelapsed %fs\n\n", (float) (clock()-start)/1000);
printf("OUTPUT: ");
for(int i=0;i<1024;i++) {
if (output[i] == 0x7A) break;
printf("%X", output[i]);
}
printf("\n");
system("PAUSE");
return 0;
}
编辑:我的问题是,为什么拨码开关的速度更快?有什么我做错了吗?
你的问题是什么? – orlp 2012-03-07 19:49:11
我的问题是为什么切换代码更快? – blez 2012-03-07 20:08:11
我编辑了我的问题。 – blez 2012-03-07 20:31:23