1. 程式人生 > >[Erlang 0129] Erlang 雜記 VI

[Erlang 0129] Erlang 雜記 VI

 把之前閱讀資料的時候記下的東西,整理了一下.

Adding special-purpose processor support to the Erlang VM

P23 簡單介紹了Erlang Compiler和Beam檔案格式;

The Erlang Compiler in short 章節提到了 Core Erlang 這個之前有提到過:

[Erlang 0120] Know a little Core Erlang

Erlang Beam Format

Python module to parse Erlang BEAM files.

P26 3.4 

The Erlang Virtual Machine

Joe Armstrong設計的JAM是Stack based machine,現在的BEAM是register based machine.

Beam Loader的章節,解決了之前的很多困惑:

     BEAM Loader作為VM的一部分其職責就是載入BEAM檔案中的程式碼.BEAM檔案使用的是所謂有限指令集( limited instruction set),這一指令集會在執行時由BEAM Loader展開為擴充套件指令集(extended instruction set).使用兩種指令集的原因是讓BEAM檔案小一點; BEAM載入邏輯在beam_load.c檔案中完成,emulator使用beam_opcodes.c檔案中的load scripts將有限指令集轉換成為擴充套件指令集;Perl指令碼beam_makeops讀取檔案ops.tab作為輸入生成beam_opcodes.c檔案.有限指令集在genop.tab.

    上面提到的檔案所在路徑:

beam_makeops erts/emulator/utils/

ops.tab erts/emulator/beam/

beam_opcodes.c erts/emulator/<machine>/opt/smp/

beam_load.c erts/emulator/beam/

genop.tab lib/compiler/src/

   檔案beam_opcodes.c是在Erlang編譯期生成的.

Exploring Alternative Memory Architectures for Erlang:Implementation and Performance Evaluation
“Processes are the basic system structuring elements. But do not use processes and message passing when a function call can be used instead.” 

這也就是小訊息大運算背後的原因.


Heap Architectures for Concurrent Languages using Message Passing

摘要: We describe how interprocess communication and garbage collection happens in each architecture, and extensively discuss the tradeoffs that are involved. In an implementation set-
ting (the Erlang/OTP system) where the rest of the runtime system is unchanged, we present a detailed experimental comparison between these architectures using both synthetic programs and large commercial products as benchmarks.
備註: 一句話總結這篇論文就是:當訊息傳遞的時候本質上發生了什麼

P3

Stack用來存放function arguments, return addresses, and local variables.複合資料結構(Compound terms)比如 lists, tuples, 以及超過一個機器字長的浮點數或者bignums都會在heap存放.stack和heap向對方區域增長,這樣做的好處是很容易做溢位檢測,只要比較一下stack和heap的指標即可,這樣設計的缺點是stack或heap的一個記憶體區域的重新分配會同時影響stack和heap兩塊區域.Erlang還支援大塊的二進位制資料,這種資料不是在heap儲存而是在單獨的全域性記憶體區域儲存並進行引用計數.

訊息傳遞是通過拷貝完成的,從sender的heap拷貝到receiver的heap;然後把指向這個訊息的指標插入到receiver的mailbox,mailbox包含在程序的PCB內.下面的圖

 

P1程序內有一些共享的資料部分在拷貝的過程中會被展開,這種情況下拷貝之後的訊息就要比之前的訊息佔用更大空間,這種情況實際情況很少發生.這種情況是可以通過跟蹤手段(marking technique)和轉向指標( forwarding pointers)來規避,但是這樣可能讓訊息通訊更慢.

關於forwarding pointer的資料:

forwarding pointer
Some garbage collectors move reachable objects into another space. They leave a forwarding pointer, a special reference pointing to the new location, in the old location.

The following difference between the two memory architectures also deserves to be mentioned: In a process-centric system, it is easy to impose limits on the space resources that a particular (type of) process can use. Doing this in a shared heap system is significantly more complicated and probably quite costly. Currently, this ability is not required by Erlang.

Efficient memory management for concurrent programs that use message passing I,II

備註: 這其實是一個論文集

P13 1.3 Improving message passing
In the private heap architecture, the send operation consists of three parts:
1. Calculate the size of the message to allocate space in the receiver’s heap;
2. copy the message data to the receiver’s heap; and finally,
3. deliver the message to the receiver’s message queue.

To reduce the complexity of the send operation, we want to remove the parts of the send whose cost is proportional to the message size, namely 1 and 2. By introducing a new memory architecture, where all process-local heaps are replaced by a shared memory area, we can achieve this and reduce the cost of sending messages to O(1), that is, make it a constant time operation. We call this the shared heap architecture.

備註: 簡單描述Core Erlang 和Erlang的關係,發展歷史 從Erlang程式碼到Core Erlang程式碼中間經歷的分析和轉換過程中是怎樣被大大簡化的.

All you wanted to know about the HiPE compiler (but might have been afraid to ask) 備註:幾乎解答了HIPE的所有常見問題   首先Erlang/OTP compiler完成巨集預處理,解析,把一些語法糖還原,之後程式碼重寫成Core Erlang的形式.在Core Erlang環節會完成各種優化比如常量展開(constant folding),函式inline等等.之後程式碼重寫成為BEAM 虛擬機器程式碼,這個環節還有一些優化. 
1> c(my module, [native]).

compile:file(my module, [native])

erlc +native my module.erl

erlc +native +’{hipe,[verbose]}’ my module.erl

Generating native code and loading it on-the-fly into the system is possible even in cases when the Erlang source code is not available but the .beam file (containing BEAM bytecode) exists. This can be done for whole modules using: 

hipe:c(my module)

hipe:c({M,F,A}). 

 

3> c(my module, [native, {hipe, [verbose, o3]}]).

c(my module, [native, core]).  %% Compilation from Core Erlang

 

警告:

Do not use the -compile(export_all) directive. This reduces the likelihood of functions being inlined, and makes useful type analysis impossible.