contributed by <eeuserp
>, <SaragCheng
>
與執行前編譯好執行檔不一樣,JIT 是一邊執行程式一邊編譯,可以直接將程式碼轉成機械碼或是其他形式執行。常常使用在 dynamic programming language。
將 brainfuck 編譯成組語
cmpb $0, (%r12)
takes a byte that r12 point to and compare with 0
if (b < 0) a++;
可更換為沒有分支的版本:
a -= b >> 31;
function increment(hi, lo):
if lo < 255:
return (hi, lo + 1)
return (hi + 1, 0)
最佳化策略:
輸入make bench-jit-x64
測試結果:
Executing Brainf*ck benchmark suite. Be patient.
progs/awib.b GOOD 116.0ms
progs/mandelbrot.b GOOD 4213.6ms
progs/hanoi.b GOOD 10782.6ms
if(*(p+1) == '-'&&*(p+2) == ']'){
| mov byte [PTR], 0
}
Executing Brainf*ck benchmark suite. Be patient.
progs/awib.b GOOD 91.5ms
progs/mandelbrot.b GOOD 4149.0ms
progs/hanoi.b GOOD 4204.0ms
[-]
敘述 ,而 awib.b 只有極少量(14%)的[-]
敘述
int continuous_count(char *p)
{
char *ptr = p;
int count = 0;
while (*ptr == *p) {
count++;
ptr++;
}
return count;
}
利用add
sub
指令修改 for loop 中 >
<
+
-
4 個 case ,指令用法如下
add <reg>,<con>
add <mem>,<con>
example:
add BYTE PTR [var], 10 // add 10 to the single byte stored at memory address var
add eax, 10 // EAX ← EAX + 10
Executing Brainf*ck benchmark suite. Be patient.
progs/awib.b GOOD 56.4ms
progs/mandelbrot.b GOOD 1551.1ms
progs/hanoi.b GOOD 5372.3ms
if(count == 1)
這個分支可以拿掉嗎?應該會更快?SarahCheng
int check_loops(char *p,int *index,int *mult)
{
int res,offset = 0,_index = 0;
if (*(p+1) != '-') return -1; //不合這三種 loop
p += 2;
while (*p != ']') { //not end of loop
if (*p == '[' || *p == '-' ||
*p == '.' || *p == ',')
return -1; //不合這三種 loop
res = continuous_count(p);
if (*p == '>') offset += res;
else if (*p == '<') offset -= res;
else if (*p == '+') {
index[_index] = offset;
mult[_index] = res;
_index++;
}
p += res;
}
if (offset != 0) return -1;//不合法的loop,沒有回到第一個p
return _index; //_index==0:clear; else:copy,multi;
}
以上這段程式碼將 copy 視為 Multiplication 中 * 1的狀況
index[ ]
儲存的是目的位址相較現在位址的位移量
mult[ ]
儲存的是要乘多少( +
的個數)
這個程式碼的精妙之處在於可以隨意以任何位址作目的位址,而且不局限於參考資料中的兩次
[
case :
_index=check_loops(p,idx,mult);
length = sizeof(index)/sizeof(int);
if(_index==0){
| mov byte [PTR], 0
}
else{
while(i<length){
| push r8
| push r9
| movzx r8, byte [PTR]
| imul r8, mult[i]
| mov r9, PTR
| add r9,idx[i]
| add byte [r9],r8b
|
| pop r9
| pop r8
i++;
}
}
註 : 不知道為什麼加上clike=
整個程式碼區塊就會走鐘
Executing Brainf*ck benchmark suite. Be patient.
progs/awib.b GOOD 47.4ms
progs/mandelbrot.b GOOD 1516.5ms
progs/hanoi.b GOOD 178.5ms
相較於位優化版本 awib.b 的執行速度提升了約2.45倍 , mandelbrot.b的執行速度提升了約2.78倍 , hanoi.b 的執行速度提升了約60.40倍。觀察可以得知 Clear loops & Copy loops & Multiplication loops 的處理對 hanoi.b 有非常巨大的幫助,因為光是clear loops 和 copy loops就佔了整個程式碼的80%。對mandelbrot.b沒什麼影響。
length_idx: 128 length_index: 0, so it can work because it didn't run the loop
Q1.does our ptr move forward by 'count'?
Q2.take away the codemov byte [PTR],0
, the error still exist
WHAT'S THE PROBLEM ABOUT WHILE LOOP? SarahCheng
try this:
while(x==1){
//Do something
}
The same loop in assembler:
jmp loop1 ; Jump to condition first
cloop1 nop ; Execute the content of the loop
loop1 cmp ax,1 ; Check the condition
je cloop1 ; Jump to content of the loop if met
deal with the variable 'length', not sure does it work or not
register int *length asm ("r10");
variable to reg
那這樣還要push r10嗎?
| add byte [PTR],r8b
output:
progs/awib.b bad output: expected 3b4f9a78ec3ee32e05969e108916a4affa0c2bba got 93898477b77b662771e12579cd4d1b7ad1771d1d
��� ������������
progs/mandelbrot.b bad output: expected b77a017f811831f0b74e0d69c08b78e620dbda2b got da39a3ee5e6b4b0d3255bfef95601890afd80709
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/bin/ld: cannot find crt1.o: No such file or directory
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/bin/ld: cannot find crti.o: No such file or directory
collect2: error: ld returned 1 exit status
Makefile:64: recipe for target 'jit-arm' failed
make: *** [jit-arm] Error 1
有照著github上的指示安裝套件了 eeuserp
試著用
sudo apt-get install gcc-multilib
來安裝必要的套件 jserv
可以參考 https://hackmd.io/s/ryDY1CPyl
施雨妏
error: bad operand size in "imul rb,i?":| imul ah, mult[i]
maybe: ah x86的 8 bits register,但是乘法必須是32 bits的register SarahCheng
error: mixed operand size in "mov rq,xb":| mov rax, byte [PTR]
#include <windows.h>
there is a func: ARRAYSIZE()
SarahCheng
ref
error: array size missing in ‘index’int index[];
missing terminating ' character [-Werror] case '.:
printf("PTR:%s, index[0]:%d",p,index[0]);
不知道為什麼是這結果
好用!!eeuserp