bir arkadaşımın önerisi üzerine şöyle bir kod denedim :
module main;
import std.stdio;
import std.path;
import core.memory;
import std.datetime;
struct opst
{
void* op;
int p1;
int p2;
int* a1;
int* a2;
opst* n;
}
enum opcs : int
{
mov = 0,mov2re,mov2ra,
push,pop,
loop,loopend,
add,sub,mul,div,
rsr,nop,hlt
}
class VM
{
int* smem;
int* smemc;
int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,b0,b1,b2,b3,b4,b5 = 0;
void*[opcs] opcL;
this(int memsize = 4096)
{
smem = cast(int*)GC.malloc(memsize);
smemc = smem;
opst* frst = cast(opst*)0;
run(frst,true);
}
int run(opst* top,bool fr = false)
{
void* pc;
if(fr)
{
asm{ call l_mov ;};opcL[opcs.mov ] = pc + 0x1;
asm{ call l_mov2re ;};opcL[opcs.mov2re ] = pc + 0x1;
asm{ call l_mov2ra ;};opcL[opcs.mov2ra ] = pc + 0x1;
asm{ call l_push ;};opcL[opcs.push ] = pc + 0x1;
asm{ call l_pop ;};opcL[opcs.pop ] = pc + 0x1;
asm{ call l_loop ;};opcL[opcs.loop ] = pc + 0x1;
asm{ call l_loopend ;};opcL[opcs.loopend] = pc + 0x1;
asm{ call l_add ;};opcL[opcs.add ] = pc + 0x1;
asm{ call l_sub ;};opcL[opcs.sub ] = pc + 0x1;
asm{ call l_mul ;};opcL[opcs.mul ] = pc + 0x1;
asm{ call l_div ;};opcL[opcs.div ] = pc + 0x1;
asm{ call l_nop ;};opcL[opcs.nop ] = pc + 0x1;
asm{ call l_hlt ;};opcL[opcs.hlt ] = pc + 0x1;
asm{ call l_rsr ;};opcL[opcs.rsr ] = pc + 0x1;
return 0;
}
sUP:
void* jmpaddr = top.op;
asm{ jmp jmpaddr[EBP]; }
l_mov:
asm{ call taddr; ret;}
*(top.a1) = *(top.a2);
top = top.n;
goto sUP;
l_mov2re:
asm{ call taddr; ret;}
*(top.a1) = top.p1;
top = top.n;
goto sUP;
l_mov2ra:
asm{ call taddr; ret;}
*smemc = top.p1;
smemc++;
top = top.n;
goto sUP;
l_push:
asm{ call taddr; ret;}
*smemc = *(top.a1);
smemc++;
top = top.n;
goto sUP;
l_pop:
asm{ call taddr; ret;}
smemc--;
*(top.a1) = *smemc ;
top = top.n;
goto sUP;
l_loop:
asm{ call taddr; ret;}
b5 = top.p1;
top = top.n;
b4 = cast(int)top;
goto sUP;
l_loopend:
asm{ call taddr; ret;}
if(b3<b5)
{
top = cast(opst*)b4;
b3++;
}
else
top = top.n;
goto sUP;
l_add:
asm{ call taddr; ret;}
*(top.a1) += *(top.a2);
top = top.n;
goto sUP;
l_sub:
asm{ call taddr; ret;}
*(top.a1) -= *(top.a2);
top = top.n;
goto sUP;
l_mul:
asm{ call taddr; ret;}
*(top.a1) *= *(top.a2);
top = top.n;
goto sUP;
l_div:
asm{ call taddr; ret;}
*(top.a1) /= *(top.a2);
top = top.n;
goto sUP;
l_nop:
asm{ call taddr; ret;}
top = top.n;
goto sUP;
l_rsr:
asm{ call taddr; ret;}
a0 = a1 = a2 =a3 = a4 = a5 = a6 = a7 = a8 = a9 = b0 = b1 = b2 = b3 = b4 = b5 = 0;
top = top.n;
goto sUP;
l_hlt:
asm{ call taddr; ret;}
goto sDown;
sDown:
return 0;
taddr:
asm
{
pop EBX;
mov pc[EBP],EBX;
ret;
}
}
}
int[string] locc;
int[string] cmax;
opst[string] pOPcs;
opst* current;
void addOP(VM vm,string page,opcs op,int p1 = 0,int p2 = 0,int* a1 = cast(int*)0,int* a2 = cast(int*)0)
{
if(page !in pOPcs)
{
pOPcs[page] = opst(vm.opcL[op],p1,p2,a1,a2);
current = &pOPcs[page];
}
else
{
opst* p = cast(opst*)GC.malloc(opst.sizeof);
(*p) = opst(vm.opcL[op],p1,p2,a1,a2);
current.n = p;
current = (*current).n;
}
}
int main(string[] argv)
{
VM vm = new VM();
addOP(vm,"test",opcs.mov2re,2,0,&vm.a0);
addOP(vm,"test",opcs.mov2re,3,0,&vm.a1);
addOP(vm,"test",opcs.loop,1000000);
addOP(vm,"test",opcs.add,0,0,&vm.a0,&vm.a1);
addOP(vm,"test",opcs.loopend);
addOP(vm,"test",opcs.hlt);
auto currentTime1 = Clock.currTime();
vm.run(&pOPcs["test"]);
auto currentTime2 = Clock.currTime();
writeln(currentTime2-currentTime1);
writeln(vm.a0);
while(1){}
return 0;
}
ama buda çok kararsız arraydan hızlı olmasına rağmen bazen arrayla aynı hızda çıkabiliyor.
(benim bilgisayar için
array = 18-20 ms
bu kod = 10-20 ms
) çok yüksek bir değişme aralığı var ve istediğim performansı vermiyor.
Bundan önce ise
module main;
import std.stdio;
import std.path;
import core.memory;
import std.datetime;
struct opst
{
void* op;
int p1;
int p2;
int* a1;
int* a2;
}
enum opcs : int
{
mov = 0,mov2re,mov2ra,
push,pop,
loop,loopend,
add,sub,mul,div,
rsr,nop,hlt
}
class VM
{
int* smem;
int* smemc;
int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,b0,b1,b2,b3,b4,b5 = 0;
void*[opcs] opcL;
this(int memsize = 4096)
{
smem = cast(int*)GC.malloc(memsize);
smemc = smem;
opst* frst = cast(opst*)0;
run(frst,true);
}
int run(opst* top,bool fr = false)
{
void* pc;
if(fr)
{
asm{ call l_mov ;};opcL[opcs.mov ] = pc + 0x1;
asm{ call l_mov2re ;};opcL[opcs.mov2re ] = pc + 0x1;
asm{ call l_mov2ra ;};opcL[opcs.mov2ra ] = pc + 0x1;
asm{ call l_push ;};opcL[opcs.push ] = pc + 0x1;
asm{ call l_pop ;};opcL[opcs.pop ] = pc + 0x1;
asm{ call l_loop ;};opcL[opcs.loop ] = pc + 0x1;
asm{ call l_loopend ;};opcL[opcs.loopend] = pc + 0x1;
asm{ call l_add ;};opcL[opcs.add ] = pc + 0x1;
asm{ call l_sub ;};opcL[opcs.sub ] = pc + 0x1;
asm{ call l_mul ;};opcL[opcs.mul ] = pc + 0x1;
asm{ call l_div ;};opcL[opcs.div ] = pc + 0x1;
asm{ call l_nop ;};opcL[opcs.nop ] = pc + 0x1;
asm{ call l_hlt ;};opcL[opcs.hlt ] = pc + 0x1;
asm{ call l_rsr ;};opcL[opcs.rsr ] = pc + 0x1;
return 0;
}
sUP:
void* jmpaddr = top.op;
asm{ jmp jmpaddr[EBP]; }
l_mov:
asm{ call taddr; ret;}
*(top.a1) = *(top.a2);
top++;
goto sUP;
l_mov2re:
asm{ call taddr; ret;}
*(top.a1) = top.p1;
top++;
goto sUP;
l_mov2ra:
asm{ call taddr; ret;}
*smemc = top.p1;
smemc++;
top++;
goto sUP;
l_push:
asm{ call taddr; ret;}
*smemc = *(top.a1);
smemc++;
top++;
goto sUP;
l_pop:
asm{ call taddr; ret;}
smemc--;
*(top.a1) = *smemc ;
top++;
goto sUP;
l_loop:
asm{ call taddr; ret;}
b5 = top.p1;
top++;
b4 = cast(int)top;
goto sUP;
l_loopend:
asm{ call taddr; ret;}
if(b3<b5)
{
top = cast(opst*)b4;
b3++;
}
else
top++;
goto sUP;
l_add:
asm{ call taddr; ret;}
*(top.a1) += *(top.a2);
top++;
goto sUP;
l_sub:
asm{ call taddr; ret;}
*(top.a1) -= *(top.a2);
top++;
goto sUP;
l_mul:
asm{ call taddr; ret;}
*(top.a1) *= *(top.a2);
top++;
goto sUP;
l_div:
asm{ call taddr; ret;}
*(top.a1) /= *(top.a2);
top++;
goto sUP;
l_nop:
asm{ call taddr; ret;}
top++;
goto sUP;
l_rsr:
asm{ call taddr; ret;}
a0 = a1 = a2 =a3 = a4 = a5 = a6 = a7 = a8 = a9 = b0 = b1 = b2 = b3 = b4 = b5 = 0;
top++;
goto sUP;
l_hlt:
asm{ call taddr; ret;}
goto sDown;
sDown:
return 0;
taddr:
asm
{
pop EBX;
mov pc[EBP],EBX;
ret;
}
}
}
int[string] locc;
int[string] cmax;
opst*[string] pOPcs;
void addOP(VM vm,string page,opcs op,int p1 = 0,int p2 = 0,int* a1 = cast(int*)0,int* a2 = cast(int*)0)
{
if(page !in pOPcs)
{
cmax[page] = 10;
locc[page] = 0;
pOPcs[page] = cast(opst*)GC.malloc(cmax[page]*opst.sizeof);
}
else
{
if(!(locc[page]<cmax[page]))
{
cmax[page] += 10;
pOPcs[page] = cast(opst*)GC.realloc(pOPcs[page], cmax[page] * opst.sizeof);
}
}
*(cast(opst*)((cast(int)pOPcs[page]) + (locc[page] * opst.sizeof))) = opst(vm.opcL[op],p1,p2,a1,a2);
locc[page]++;
}
int main(string[] argv)
{
VM vm = new VM();
addOP(vm,"test",opcs.mov2re,2,0,&vm.a0);
addOP(vm,"test",opcs.mov2re,5,0,&vm.a1);
addOP(vm,"test",opcs.loop,1000000);
addOP(vm,"test",opcs.add,0,0,&vm.a0,&vm.a1);
addOP(vm,"test",opcs.loopend);
addOP(vm,"test",opcs.hlt);
auto currentTime1 = Clock.currTime();
vm.run(pOPcs["test"]);
auto currentTime2 = Clock.currTime();
writeln(currentTime2-currentTime1);
writeln(vm.a0);
while(1){}
return 0;
}
bu şekilde bir kod yazdım ve 5-8 ms aralığında zaman alıyor. Ulaşmak istediğim performans bu fakat bu koddada addOP fonksiyonundaki realloc da sorun var sanırım. ilk 10 tane op için sorun çıkarmasada(bunları malloc ile açtığımdan) sonrasında realloc u kullanamadığım için daha fazla struct ekleyemiyorum bu sorunu aşabilirsem performans açısından (benim için en azından) çok iyi olacak.
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]