
第一次放天燈好像是大一迎新露營,在小叮噹科學園區,而且還是自已做的喔。
第二天本來想在社團營隊時候在交大放,不過考慮旁邊有變電所加油站就取消了
真正的第二次是三年前的去平溪玩的事,不過同行的人也不在身邊。祝福她,希望她過的很好...:>


我也來寫一下
1 google 對V8的benchmark有取巧之嫌(我覺得是作弊)
簡單說,假如java script engine 需要作三件事:吃、喝、拉,V8 特別會"拉",google 的test suite 就特別
大量的測"拉"的行為,所以 出來的數據會差那多。
ref: http://ejohn.org/blog/javascript-performance-rundown/
http://weblogs.mozillazine.org/roadmap/archives/2008/09/tracemonkey_update.html
2 不是一個tab 一隻process
應該是同一個主網址的網頁會用同一隻process,有圖有真相。
所以如果同一個process下的tab 掛了,那整隻process也就bye bye 啦。而且我覺得google只是把memory
和thread control/share 的問題往os 丟而以。
3 記憶體"不見得"比較省
沒有正式的benchmark,有人提到而以
http://jedi.org/blog/archives/005829.html
http://digg.com/software/My_Google_Chrome_memory_usage_after_5hrs
4 nightly build auto downloader chrome 每幾個revision 就有吐一個nightly build 出來,每次要自已上去看太
麻煩了,有人寫了一個auto downloader 可以自動尋找最新版本,選擇要抓zip or exe
5 icon 很像"強殖裝甲"卡巴晶核
也有人覺得像其它東西...:P
日期:2008.04.20
成員:軟趴趴,osban
天氣:陰
交通工具:機車兩台
0700 新竹龍山社區吃完早餐出發
0815 登山口停車場,出發。要不是上山路時前面的車子塞在了,還可以更快到。另外過向天湖到鹿場之間塌掉路已經修好了
0820 登山口,路牌,取左進山
0825 路牌,直行哈堪尼斯,取右加里山
0840 渡溪,有高級小木橋。跟在我們後面的跑的米格魯不敢過橋,很蠢。
0850 有一紅路指向路牌,之字型取右
0855 1k 樁
0905 木橋,溪溝向左流,我們都在這取水,佳里山的水真是他媽的好喝,而且冰到不行
0920 路牌,回1.5 K,直行 1.7K
0925 新的高級小木屋,4號樁,有一叉路往大坪登山口,左上加里山,休息先。
0935 go
0950 累,休息
1005 go
1015 1.5k 椿
1025 8號樁 1980m,有木椅,有空地可搭個三頂帳吧,喘先
1032 9號樁,叉路,直行不知去那,但有空地可搭帳,取左續行
1106 3k樁 在陵線上,如果不想登頂,到這邊也行
1120 登頂,雖然天氣陰陰的,但是有展望,看得到聖陵線,不過坐十分鐘霧就上來了。
1135 沒午餐吃,快閃
1220 8 號樁,遇台中某小學為了爬玉山來綀體力,讓他們請了一頓,莊老師謝啦
1245 go
1315 2k 樁
1327 山屋,4號樁
1350 溪溝,裝水回家喝
1410 風美溪,泡腳,夏天再來玩水吧
1425 go
1445 停車場
後記:加里山還是一樣美,松葉林真的很棒。回來後跟房東聊了一下,他說8年前他們去爬的時候,過風美溪沒木橋的,開始一段上坡沒木梯,爬起來超累。

上一篇有講到 0.9.1 之前 dynamic code generation 是用稱為dyngen 的方式(請自已看上篇,我不會做連結),這個方式有一些問題(我自已掰的,可能是錯的)
1. compiler issue
00000000000001e7 <op_addl_T1_T2>:
1e7: 45 01 ec add %r13d,%r12d
1ea: c3 retq00000000000001eb <op_subl_T1_T2>:
1eb: 45 29 ec sub %r13d,%r12d
1ee: c3 retq00000000000001ef <op_addl_T0_T1>:
1ef: 45 01 e7 add %r12d,%r15d
1f2: c3 retq
上面是compile op.c 產生的code,有沒有發現怎麼每個function block 都這麼小呢?一般的function 都有 prolog 和epilog,dyngen 為了精確的決定operation function 所對應host code,所以利用 -O2 -no-strict-aliasing (不知道在幹嘛的)拿掉prolog 和epilog,而且確保 return instruction 是在最後一個,才知道要copy 多少instruction 走。這套方法在gcc 3.x 版運作的很好,但是在gcc 4.x 版,return instruction 會被塞在function block 的中間,那就吃屎啦。可以去看一下maillist 有一堆在哭為什麼 gcc 4 不能用的討論,但隨著linux distribution 都採用gcc 4 為預設compiler,而且這世界上又不是只有gcc,這個問題必需要解決。
2.optimization issue
假設我們的target code 為
add r1, r2, r3
xor r4, r2, r3
sub r5, r2, r3
則經過dyngen maping 到的host code 大概會像這樣
mov T1, r2
mov T2, r3
add T0, T1, T2
mov r1, T0
mov T1, r2
mov T2, r3
xor T0, T1, T2
mov r4, T0
mov T1, r2
mov T2, r3
sub T0, T1, T2
mov r5, T0
有看到問題嗎?r1, r2 的值本來就在T1,T2為什麼我還要一直重覆搬呢?因為dyngen的scope 只限在單一的target instruction,對於其它人的行為沒有辦法處理
3 porting issue
要將qemu port 到新的target 要做的事情就是先定義opertion function,可是cpu 其實每個都差不多阿,誰家cpu沒有 add, xor, sub, and,等等的東西,
每個都要定義自已的一套非常煩人,是不是可以有一共通的架構呢?
為了以上問題,2008/02/01 Fabrice Bellard 和 Paul Brook 引進了TCG, tiny code generator。
怎麼運作的呢?我也不懂,但是其實就是一個小型的compiler,TCG定義了自已的operation function(intermediate code),可以以basic block 為單位做optimization,比如說(後面的32是指這個是32bit instruction)
and_i32 t0, t0, $0xffffffff
就會被拿掉,或者是
add_i32 t0, t1, t2
add_i32 t0, t0, $1
mov_i32 t0, $1
只有最後一個instruction 會被保留。還有一堆有的沒有的功能,請看這裡
另外作者說,TCG是可以跟dyngen混用的,但還是希望以後所以的target都可以轉到TCK這個framework,目前在cvs看得的只有x86和cris,3/31時Paul Brook已經
把arm由dyngen 轉到TCG了,但他說還需要一些clean up,等他commit 上去再來看看吧,x86你爸很不熟。
在qmeu中,將qmeu 本身所執行的平台稱為 host,模擬的平台稱target,而將target code 轉為 host code 的過程稱為code generation。但因為qemu 是在動態執行中將target code 轉為 host code,所以多加了一個dynammic來形容。而整個過程在qemu 中稱為 dyngen。
0.9.1 版之前的dyngen 概念很簡單(但實作起來有很多細部的東東,整個就是複雜),dyegen 定義了四個pesudo register:env, T0, T1, T2,這四個register分別mapping 到 host 上真實的general register,在x86上就是 ebp, ebx, esi, edi,在x86_64上就是 r14, r15, r12, r13 (為什麼不是r12, r13, 14, 15,怪),定義在dyngen-exec.h
之後target 必需定義一些簡單的operation function,此operation function 被定義在每個 target-machine/op.c ,底下是target-arm 的例是,每個平台大同小異
,這些operation 很簡單,定義如何在pesudo register 之間搬資料,做一些簡單的動作。
void OPPROTO op_movl_T0_T1(void)
{
T0 = T1;
}void OPPROTO op_movl_T1_im(void)
{
T1 = PARAM1;
}void OPPROTO op_addl_T1_im(void)
{
T1 += PARAM1;
}void OPPROTO op_addl_T1_T2(void)
{
T1 += T2;
}void OPPROTO op_subl_T1_T2(void)
{
T1 -= T2;
}
有了這些基本的operation後,在build qemu時會將的會將op.c 編譯成 op.o,再從op.o 將每個operation 所對應的host code抽出來,產生op.h opc.h,target-machine/translate.c 利用產生出來的個這兩個header file將每個target instruction 對應到數個operation function。就像底下的arm 例子,
op = (insn >> 11) & 3;
rd = (insn >> 8) & 0x7;
if (op == 0) {
gen_op_movl_T0_im(insn & 0xff);
} else {
gen_movl_T0_reg(s, rd);
gen_op_movl_T1_im(insn & 0xff);
}
switch (op) {
case 0: /* mov */
gen_op_logic_T0_cc();
break;
case 1: /* cmp */
gen_op_subl_T0_T1_cc();
break;
case 2: /* add */
gen_op_addl_T0_T1_cc();
break;
case 3: /* sub */
gen_op_subl_T0_T1_cc();
break;
}
if (op != 1)
gen_movl_reg_T0(s, rd);
底下是截取 objdump op.o 的部份,dyngen 會把retq 以上的部份copy 出來,再經過一些patch 就產生相對應的code 啦,上面粗體的gen_xxx_xxx的function 就會把相對應的找出來,轉換就完成啦
00000000000001e7 <op_addl_T1_T2>:
1e7: 45 01 ec add %r13d,%r12d
1ea: c3 retq00000000000001eb <op_subl_T1_T2>:
1eb: 45 29 ec sub %r13d,%r12d
1ee: c3 retq00000000000001ef <op_addl_T0_T1>:
1ef: 45 01 e7 add %r12d,%r15d
1f2: c3 retq
講起來好像很簡單,那是因為假裝略過 control flow 的東東,有興趣的人自已看吧,講寫的東東其實是第二篇,先騙騙錢。
生活(6)
旅遊(1)
網路(1)
運動(4)
語言(2)
電腦雜項(0)
programming(2)