contributed by <hugikun999
>, <ponsheng
>
http://www.voy.com/245963/
github page : https://github.com/ponsheng/jit-construct
學習設計 JIT 編譯器
運用計算機組織的背景知識,進行深入效能評估和提出改善方案
延展程式語言,提供 concurrency 能力
JIT compile (動態編譯)在程式執行階段才把程式編譯成 machine language ,同時進行程式優化
通常程式會出現兩種現象,因此可以對應做優化
這次作業要優化第2種現象(BF 沒有 subroutine 的概念)
JIT 的優化範例可見第二個參考網址
(1)Understanding the differences
(2)JIT-compiler
(3)What is the difference between a compiler and an interpreter?
直譯器(interpreter) v.s 編譯器(compiler)
直譯器會在程式執行時才將原始碼一行一行轉譯並在轉譯後立即執行,相對於直接執行編譯器所產生的機械碼花費更多的時間。但是編譯器必須先將原始碼編譯成可執行碼之後才會執行,相比之下直譯的動作會更省時間。
sed語法
magic code
: an informal term of abstractionfinal
: if a thing is to be declear with the label final
,the thing can't to be inherit by other.virtual
: if a thing is to be declear with the label virtual
,it will be late binding(dynamic binding).late binding
: the method being called upon an object or the function being called with arguments is looked up by name at runtime.contraction
將連續性的+
、-
、>
、<
統計總次數後做一次性的處理。
形式:+++++
code: *p += 5;
clear loop
將迴圈歸零的形式[-]
,直接改成將值設為0。
形式:[-]
code: *p = 0;
copy loops
直接將當前指標的值加給迴圈內牽涉到的其他指標的值。
形式:[->+<]
code: *(p + 1) += *p;
multiplication loops
類似 copy loops 的方法,如果迴圈內是對同一個指標做多次的+
、-
,可以利用當前指標的值乘上加總次數加給目標指標。
形式:[->+++<]
code:*(p + 1) = *p * 3 ;
scan loops
在較多的[>]
、[<]
情況下才有好的效能改善,在C語言中可以利用 memchr()
、memrchr()
來取代原本的寫法。
operation offsets
事先計算對哪些指標做了什麼事,直接將 p
加上offset做運算,而不必依照 program 的順序一直對 p
做左移或右移。
完成一次9層河內塔
有大量連續的 +++
、---
、>>>
、<<<
,也有滿多的[-]
可以用 clear loops。
另外有在[]
內做許多連續運算可以用 multiplication loops。
BF編譯器
3個程式中唯一有出現[<]
、[>]
,可以用 scan loops 優化。
這個程式要開啟來看一下,有詳細的 Usge,還有把 bf code 排成有趣圖案
碎形程式
Lua 是一種相當普遍使用的內嵌式語言,很適合配合使用其它程式語言(例如 C 或 C++)所寫的程式。Lua 的主要目的之一是要讓對程式設計不熟悉的人也能使用,因此它的設計相當單純,適合一般人學習。
The Unofficial DynASM Documentation
A preprocessor and tiny runtime library for creating assemblers and JIT compilers in C or C++
writing a just-in-time compiler or need to generate code on the fly
把組語轉換成 opcode 型式,方便撰寫
other
(1) 複雜的宣告
這個檔案是 DynASM 的 preprocessor 的核心檔案,需要一個 DynASM 檔(可以混合 C 和 Assembly)做 input,輸出 C 檔,therein performing the bulk of the conversion from assembly to machine code.
|
: 開頭的行:原封不動|
:包含 assembly instruction 或 assembler directives,會被轉成 C 的型式:dasm_put(Dst, ...)
\
:被當做 C code,undergo prepreprocessor substitutions created by .define, and can be part of .macro definitions..arch
指定 DynASM 所使用之組語使用什麼架構
.actionlist
在 C file 中產生一個 array,內容的號碼映射到程式中使用的 assembly 的 opcode。
在.if
、.else
、.endif
前面加上|
會被視為C裏面的#if
、#else
、#endif
。
| mov aPtr, state->tape
means [aState + offsetof(bf_state_t,tape)]
dasm_init
dasm_State
所宣告的位址需要利用 dasm_init
來初始化。DASM_MAXSECTION
可以利用 |.section code
來決定section的數值。
dasm_setupglobal
dasm_init
並未完全初始化 dasm_State
還需要利用到 dasm_setupglobal
。|.globals
後面所接的變數會被視為 enum
,且包含一個 lbl_MAX
。
dasm_put(Dst, index)
執行從action list 中某個index開始的 assembly,執行方法是 "從 actionlist[index]開始取出 opcode 或是參數,再取下一位,直到收到255(the DynASM bytecode instruction DASM_STOP)停止"
ex:
問題: 程式行為是先跑過 JIT 後,將 assembly存起來(存進DynASM state),最後才轉machine code(dasm_link / dasm_encode), 是否有違JIT概念? 如果code很大怎麼半 ponsheng Chen
執行 make bench-bench-jit-x86
會以某這個環境變數去執行 python script : tests/bench.py
env PATH='.:${PATH}' BF_RUN='jit-x86' tests/bench.py
裏面執行程式的片段
stdout=subprocess.PIPE, stdin=subprocess.PIPE
:os.getenv('BF_RUN','./jit-x86'), program] + sys.argv[1:]
Note that if you want to send data to the process’s stdin, you need to create the Popen object with stdin=PIPE. Similarly, to get anything other than None in the result tuple, you need to give stdout=PIPE and/or stderr=PIPE too.
p.communicate(input=stdin + '\x00')[0]
摸索好久
http://www.cs.virginia.edu/~evans/cs216/guides/x86.html
https://en.wikibooks.org/wiki/X86_Assembly/Data_Transfer
http://sparksandflames.com/files/x86InstructionChart.html
紀錄原版時間
中英關鍵字記得以空白區隔
課程助教
OK 謝謝助教
Image Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
此方法是將多餘運算整併,例如 +++++ ,其實就是+=5,此改善方法雖然直覺簡單,但實質效益也不差,而實作方法可在遇到+ - > < 時即檢查是否為連續出現。而在此我們保留 inc 在只有出現一次的時候,可使效能最佳化。
1.+
2.+
+-
3.+
+-
+<
4.+
+-
+<
+>
Clear loops & Copy loops & Multiplication loops
[-]
[->>>+<<<]
[->>+++>+<<<]
需要注意的case
1.處理完loop後,要將指標做正確的平移
2.連續的+
之間存在空白,換行或其他無關指令
Exec time for every Program
對 Brainfuck 程式語言進行擴充,使其能夠支援 concurrency / parallelism。需要有程式語言的規格描述並且驗證。
* Bukkake: A parallel brainfuck JIT in C
* Brainfuck Process Extensions
* Parallel Brainfuck
* Concurrent Brainfuck
研究中
Brainfuck Optimization Strategies
Virtual Machine Constructions for Dummies
Just in Time Compiler ( understanding JVM working in detail )
https://github.com/rampant1018/jit-construct
#line 136 xxx.c
GCC Line Control