2010年3月28日 星期日

3/20 和 Scott 閒聊的隨手記

以下列出上週末和 Scott 聊到的東西, 大部份都是 Scott 在講啦, 真是大雜燴啊...

Software

  • Scott 想在 ReviewBoard 按 "ship it" 後照 Linux kernel 社群的習慣, 自動加上 "sign-off-by SOMEBODY", 或是接收對方的 commit。fcamel 提到或許可用 plugin 的方式在 ship it 後接自己操作, 既然都是 python code, 做起來應該不會太難。後來 Scott 查到目前 ReviewBoard 尚無這個功能 (VMWare 內部有, 但和公司 infrastructure 合得太密切, 不能 open source)。短期內不會有這功能。
  • Scott 展示 virt-manager, 和其它家 VMware 比起來, 特色是零設定。裝好 guest OS 後, 會自動設個 domain name 給 guest OS, 於是 guest OS 和 host OS 之間可以用 domain name 連來連去。不足之處是只支援 Linux OS。Ubuntu 上也有, 不過標示成實驗性套件
  • Scott 展示 Remobo, 一個強大的 VPN 軟體。用法和 Skype 差不多, 兩台機器各註冊一個帳號, 互加 「buddy」, 兩者就可以透過 Remobo 中央伺服器指派的區域 IP (7.x.x.x) 互連 。號稱什麼牆都能穿, 看起來滿方便的。而且在 Windows、各家 Linux和 Mac 上都能執行!

Profiler

  • Scott 展示如何用 sysprof 做 profiling。sysprof 是 sampling-based 的 profiler, Scott 說它簡單易用。如果作 embedded 產品,需要在產品上紀錄 profile, 拷貝回開發機器分析的話,還是 oprofile 較好。未來則可能是 perf 的天下。這還是我第一次看到 sampling-based 的 profiler。對這些東西沒有概念, 鴨子聽雷。
  • 承上, 跑 profiler 時需要有 debug info 才能找到細節, 要另外裝含 debug info 的 package。rpm 和 dpkg 都有提供含 debug info 的 package, 。在 Ubuntu 下就是安裝 X-dbg, 比方說 package "python" 的 debug info package 是 "python-dbg"。
  • 承上, 這些 debug info package 不是另外提供一套編譯時有含 debug 訊息的東西, 而是一開始就編好有含 debug 訊息的套件, 再把它拆成 X 和 X-dbg 兩份。X 裡的二進位檔有記錄 debug 資訊要去那裡找。

Testing

  • fcamel 提及近來寫測試的一些心得, 沒聊太深。待有更多經驗後我會寫到 fcamel.twbbs.org 上。
  • fcamel 打算翻譯 "Why are we embarrassed to admit that we don’t know how to write tests?", 已取得原作者許可。Scott 依自己翻譯的經驗, 說「信雅達」三者難以兼顧, 先取雅和達吧。
  • fcamel 聊到 top-down 和 bottom-up 進行 TDD 的思維不同, top-down 時使用 mock 是很有趣的體驗。發覺像 Scott 這類 system-based engineer 似乎不怎麼喜歡 OOP 搞出的一堆新名詞。印象中 Linus 也常開炮轟 C++, 網路上不少討論的文章。

Sharing

  • Scott 建議 fcamel 可以直接到自己常用的 open source 上看看有沒有什麼 issue / bug 可以解, 這樣比較容易找到可以做的事。這建議滿實用的, 比自己用用發現問題更能找到事做。等手邊雜事做完、翻完一篇別人寫的技術文後, 就來試看看吧。
  • Scott 希望 fcamel 可以多放些技術心得到 ITRS Wiki, 但 fcamel 依過去的經驗, 覺得放 blog 比較容易被 Google 搜到, 並且方便討論。過去 fcamel 曾架過 web 個人站、wiki, 觀察它們和 blog 的使用情況, 結論是 blog 較易傳播資訊。
  • fcamel 分享自己玩 micro blog、blog、wiki 和觀察 Google Analytics 的心得。micro blog 又比 blog 更易集中討論。而且從 Google Alert 觀察到 Google 近來索引 micro blog 的速度愈來愈快。plurk 上發的文章, 剛開始是一兩月後才建立索引, 現在已是隔天就建入索引。

Others

  • Scott 展示 cross compiling for Windows on Linux。操作看起來比想像中簡單許多, 不過對我這種一定有灌 Windows 來打 Game 的人來說, 暫時沒這種需求。
  • Scott 推薦用Academic Earth 練英聽, 這個站搜集名大學的課程影片。我稍微看了一下, 有不少有趣的課, 可惜沒附字幕。Scott 另外推薦用 audible.com 買有聲書來聽。這等我功力更高後再來試吧。
  • fcamel 聊到最近 Joel 寫了一系列 Mercurial 教學文, 而且還做得很精美! 好奇 Joel 打什麼主意。聽 Scott 說才知道 Joel 的公司最近在賣 Kiln, 一個含 web 介面的 Mercurial server。

2010年3月27日 星期六

用 vim 將 camel case 改成 underscore-based

昨天改這改到很累, 想到可以用 map 處理:
:map e a_<ESC>l~

接著用 /[a-z][A-Z] 搜可能是 camel case 的部份, 確定是的話就按 e 修正。接著按 n 跳到下個地方。遇到一片連續的 camel case, 就 nenenenenen ..... 用力的敲下去, 很有快感!

或是用 record 也 OK, 操作如下:
  1. qe  # 錄到 e 裡
  2. a_<ESC>l~ # 這裡是真的按 ESC 鍵
  3. q
之後一樣先搜到可疑之處, 若是的話按 @e 重播剛才錄下的操作。

2010-03-28 更新

感謝 keitheis 提供直接用 ex mode substitution 的作法, 簡化後的寫法如下:
:% s/\(\l\)\(\u\)/\1_\l\2/gc

關鍵在於後面的 \l (小寫 L) 會把下一個字元轉成小寫 (\u 則是轉大寫), 所以先用 regular expression (regexp) 記好前面的小寫 (\1) 和後面的大寫 (\2), 就很容易啦。之所以看起來這麼亂, 是因為 vim 的 regexp  語法大多要多加反斜線 。詳見 substitute 和 sub-replace-special

2010年3月26日 星期五

Ubuntu 上查詢套件被安裝的時間

這篇所言, dpkg 沒有記錄安裝時間, 不過有留 log 在 /var/log/dpkg.log。另外可參照 /var/lib/dpkg/info/*.list 建立時間。

2010年3月19日 星期五

python -m SimpleHTTPServer: 測網路的好幫手

昨天才從 victor 那看到 Top Ten One-Liners from CommandLineFu Explained, 今天就用上其中一條。

測兩台機器之間是否網路正常、無防火牆阻檔, 最好的做法就是立即跑個 server, 從 client host 用 telnet 連線看看。於是在 server host 打下面的指令, 就會有個簡易 web server 跑在 port 8000:
python -m SimpleHTTPServer 8000

再從 client host 打下面的指令連到 server:
telnet SERVER_HOST 8000
正常來說會有「Connected to ...」的字樣, 接著隨便打串字按 enter 後會收到回傳 400 的網頁。

python 內建這種模組也挺不錯的。

2010年3月18日 星期四

將 bash 設成 vi mode 並保有 ctrl+ l 清除螢幕的功能

習慣用 vi 後, 想將 bash 的操作方式也換用 vi 的方式操作, 這樣就能按 ctrl + [ 進入 normal mode, 接著用 w, b, f 暢遊在文字之間。但令人困擾的是, vi 模式的 insert mode 無法按 ctrl + l (L) 清除螢幕。

查了一下發現解法是將 ctrl + l 對應到清螢幕的功能, 總結來說, 就是這麼設:
set -o vi
bind -m vi-insert "C-l":clear-screen
其實以上都是在設定 readline 的行為, 詳細內容見 man bash (搜 "bind \[" 跳到相關章節) 和 man 3 readline (是的, 它是個 function!) 。clear-screen 是 readline 的功能之一。

與本文無關的花絮

好奇之下試著用 C 呼叫 readline:

/* f.c */
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>

int main(void) {
    char *s = readline ("promp> ");
    printf("%s\n", s);
}
編譯方式:
$ gcc f.c -lreadline -o f
在編譯前要先確定有裝 readline.h 和 libreadline.so, 不然編譯後會出現「error: readline/readline.h: No such file or directory」。

Ubuntu 下安裝方式是:
# 用 apt-file 找出 readline.h 放在那個 package 裡
$ apt-file search readline/readline.h
ghc6-doc: /usr/share/doc/ghc6-doc/libraries/readline/readline.haddock
guile-1.6-dev: /usr/include/guile-readline/readline.h
libreadline5-dev: /usr/include/readline/readline.h

$ sudo aptitude install libreadline5-dev

玩了一下還滿有趣的。

2010年3月13日 星期六

multi-core、multi-thread 以及 Java 和 Python 的 thread 實現方式

過去一直搞不懂 multi-cpu 和 multi-core 的差別, 以及 process 和 thread 的差別。今天總算一次弄明白了。

何謂 multi-core? 為何要用 multi-core?

「multi-CPU, multi-core and hyper-thread」清楚地說明三者的差別:
  • hyper-threading: 在單一 CPU 內複製 architectural state 以減少 context switch 的時間。複製的量可以不只一份, OS 會當成多個 processor 用。比方說單 CPU 複製一份 architectural state, OS 就當作有兩個 logical processor。若 OS 的 scheduling 沒有考慮到 CPU 裝置是 hyper-threading, 有可能會拖慢速度, 畢竟實際能計算的裝置仍只有一份。目前 Intel 仍有在使用這個技術。
  • multi-CPU 顧名思意很容易理解。缺點是 CPU 之間溝通費時。若 CPU 1, 2 共用同塊記憶體位址, 在 CPU 1 讀完一串資料後, CPU 2 更改了其中一個位置的值, CPU 1 必須也更新 cache 內的值。可以想見要確保多個 CPU cache 和 RAM 同步的成本有多高。
  • multi-core 的好處是在一塊晶片上做進多個 CPU (multi-CPU 則是多個晶片)。於是可先配置好資料互通的線路, 減少同步資料的時間, 亦可能共用 cache。Wikipedia 上的示意圖滿清楚的。
「多核心處理器有前途嗎?」說明為何 multi-core 是目前的主流。主要的原因有三點:
  • 提高 CPU 頻率所提昇的速度和多消耗的電不成比例, 對多數人來說這不合成本。
  • 提高 CPU 頻率讓指令更難平行化 (我看不懂這點)。
  • RAM 跟不上 CPU 的發展, 於是得發展 CPU cache 和其它技術減輕這方面的影響, 使得技術變複雜。
這樣看來, 與其在同樣的大小的晶片內做一顆更強的 CPU, 還不如降低 CPU 頻率, 在同樣大小晶片內塞入更多核心。

對 OS 來說, 不管是 multi-CPU 還是 multi-core, 都會被當作有多個 CPU 可使用。Linux 下可看 /proc/cpuinfo 了解實際上擁有的 CPU 數量和核心數 [*1]。

回頭看 CPU 共享記憶體拖慢速度的議題。若 CPU 之間不需用到同塊記憶體, 也就沒有 CPU 同步資料的問題。什麼時候 CPU 之間會共用到同塊記憶體呢? 這很常發生嗎? 答案是當 process 之間用 shared memory 溝通, 或是使用 multi-thread 時。

thread 與 multi-core / multi-CPU

multi-thread 是很常見的使用情境, 好處是容易撰寫程式之間的溝通, 溝通速度快並能減少複製同樣的資料到不同記憶體。至於 multi-thread 好還是 multi-process 好, 則是另一個議題了。

不同的 VM 實作 thread 的方式不同。green thread 指 VM 自己管 thread, 而 native thread 表示該 VM 用的 thread 等同於 OS thread。native thread 才能享有 multi-core / multi-CPU 的好處, 讓工作平行化能加快執行速度。JVM 的 thread 因版本和作業系統而異, 在 Linux 下是 native thread。可透過 ps -eLF 得知 JVM 用的 thread 是那一種。

下面是我在 四核心 CPU、Ubuntu 8.04 下的使用例子:
$ java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) 64-Bit Server VM (build 10.0-b23, mixed mode)
$ ps -eLF
UID        PID  PPID   LWP  C NLWP    SZ   RSS PSR STIME TTY          TIME CMD
...
fcamel    1145  7850  1145  0   19 353540 246044 2 Mar04 pts/8    00:00:00 java -jar selenium-server.jar
fcamel    1145  7850  1146  0   19 353540 246044 2 Mar04 pts/8    00:00:00 java -jar selenium-server.jar
fcamel    1145  7850  1147  0   19 353540 246044 2 Mar04 pts/8    00:00:00 java -jar selenium-server.jar
fcamel    1145  7850  1148  0   19 353540 246044 3 Mar04 pts/8    00:00:00 java -jar selenium-server.jar
fcamel    1145  7850  1149  0   19 353540 246044 0 Mar04 pts/8    00:00:00 java -jar selenium-server.jar
fcamel    1145  7850  1150  0   19 353540 246044 1 Mar04 pts/8    00:00:00 java -jar selenium-server.jar
...

從上表可看出 selenium-server 有一個 process ID (PID) 和多個不同的 thread ID (LWP: light-weight process), 且被分散在不同的核心上執行 (PSR: 目前該 process 被配置到那個 processor )。

雖然前文提到 native thread 可以直接被 OS 排程, 因此能用 multi-thread 平行化加速。不幸的是, CPython 使用 native thread 卻無法透過 multi-core 加速, 反而會變慢。詳細的原因請見 Dabeaz Beazley說明。目前若想平行化 CPython 的程式, 只能用 multi-process (如透過模組 multiprocess), 但這種作法多了不少搬記憶體的額外時間。

備註

  1. processor 的數量表示 Linux 可用的 CPU 量; physical id 的量表示實體 CPU 數量; 同樣的 physical id 下, 不同 processor 會有不同 core id, 其中 cpu cores 表示該 CPU 的核心數。

2010-03-14 更新

  • 參考 sby 等人的說明後, 發覺說錯 hyper threading 的部份, 更正內文。另修正其它段落一些措詞。

2010年3月6日 星期六

學習和開發 Python 的好幫手

慣用 IDE 的人會推 Eclipse + PyDev, 網路上有不少教學文章。我則是慣用 VIM + IPython

這裡有我針對 Python 設的 vim 設定檔, 有興趣用的人可以撿需要的部份用, 或是直接複制整個 .vim 和 .vimrc 也行 (若你原本沒設 .vim 和 .vimrc):

$ git clone git://github.com/fcamel/configs.git
$ cp -r configs/.vim ~
$ cp configs/.vimrc ~

推薦讀 IPython Tip Sheet 學習使用 IPython, 花個十分鐘將可獲得兩倍以上的學習速度。我常最用的指令是 ? 和 ??, 分別會秀出物件 (函式) 說明和原始碼。它的運作原理很簡單, 因為在 Python 的世界裡, 所有東西都是物件, 而物件的 __doc__ 欄位存有文件, __file__ 欄位則存有載入的檔案路徑。因此 IPython 可以輕易地讀入文件和原始碼。

如此一來, 在 screen 裡開兩個 terminal, 一個開 IPython; 一個開 VIM。想試什麼簡單程式就在 IPython 裡試, 有疑問就用 ? 和 ?? 查。在 VIM 裡可按 F10 執行內容, 方便試較長一些的程式。實際開發時則在 VIM 裡切兩個視窗, 一個寫 unit test, 一個寫 software-under-test。在 unit test 的視窗裡按 F10 執行程式, 有錯就切到 software-under-test 的視窗改。若有錯不知錯在那想了解物件內容, 則在 unit test 裡呼叫 IPython [1], 進入 IPython 內了解詳情, 寫起來很有效率。

備註

  1. 由於在 VIM 內執行 Python 已用掉 stdin, 叫起 IPython 後 IPython 會立即結束。這時得改在 shell 上執行程式, 才能從 unit test 中叫出 IPython 並繼續操作 IPython。
  2. fcamel's blog: 強化 Python 在 Vim 裡的顏色

2010年3月4日 星期四

透過 PPA 在 Ubuntu 上安裝 Firefox 3.6

今天要裝 Firebug 時才發現 8.04 (hardy) 的 Firefox 是 3.0 版。最新的 Firebug 不支援 3.0。於是研究一下怎麼裝 Firefox 3.6, 還看到有人藉此抱怨為啥 Linux 仍無法普及

PPA (personal package archive) 是 Ubuntu 用來讓一般用戶散佈 package 的站台, 最近 Firefox Stable Channel Packages 上傳了 Firefox 3.6. 透過 PPA 可以簡單地安裝 Firefox 3.6。 9.10 之前的安裝方法如下:

$ echo "deb http://ppa.launchpad.net/mozillateam/firefox-stable/ubuntu  $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list
$ echo "deb-src http://ppa.launchpad.net/mozillateam/firefox-stable/ubuntu   $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CE49EC21
$ sudo aptitude update
$ sudo aptitude install firefox

說明:
  • 設定PPA 的教學講得滿清楚的,  對照自己要用的軟體資訊 (如  Firefox Stable Channel Packages), 替換下載 package 的網址和驗證用的 key 即可。這兩者的資訊寫在每個 PPA 站台的「Technical details about this PPA」。
  • lsb_release 會列出 Linux Standard Base 資訊。
  • 若要試最新版的話, 可以改用 PPA for Ubuntu Mozilla Daily Build Team。我一開始照這篇說的試, 不過沒成功, 懶得再找原因了。

sudo echo / cat 發生 permission denied

下面是失敗的例子:
$ echo "deb http://ppa.launchpad.net/gwibber-daily/ppa/ubuntu $(lsb_release -sc) main" >> /etc/apt/sources.list
bash: /etc/apt/sources.list: Permission denied

這篇所言, 問題出在 ">>" 仍是原本 bash 執行的, 不具 root 權限。解法是改對 tee 下 sudo, 別透過 ">>":

echo "deb http://ppa.launchpad.net/gwibber-daily/ppa/ubuntu $(lsb_release -sc) main" | sudo tee -a  /etc/apt/sources.list

2010年3月2日 星期二

Old notes about Engine in High performance MySQL 1/e

很久以前寫在 Wiki 上的, 自己都忘了有寫過, 補貼到這增加日後回憶的機會。

Feature

  • MyISAM: query fast, no transactino
  • BDB: medium (BDB is in MySQL-Max, not in the default installation)
  • InnoDB: good transaction

Locking

  • MyISAM: lock a whole file
  • BDB: lock a page (8K)
  • InnoDB: lock a row

Index

  • UNIQUE has the same efforts as INDEX
  • the index order is important: e.g. index (first_name, last_name) means that selecting by last_name won't have effects of index
  • MyISAM:
    • B-Tree or R-Tree (spatial index, since v4.1)
    • has FullText Index
    • the indexes and data are stored in separated files
    • index = (index column, row offset)
    • Primary key = NOT NULL + UNIQUE + INDEX, which is not necessary
    • R-Tree: http://jeremy.zawodny.com/blog/archives/000418.html
    • the standard of spatial query syntax: http://www.opengeospatial.org/
    • FullText Index: word base, so query partial words such as ”%est” can't take the advantage
  • Heap: Hash, B-Tree
  • BDB
    • B-Tree only, although BDB should use hash tables in common sense
    • PK is necessary, if there is not, MySQL will add a hidden one
  • InnoDB:
    • B-Tree only
    • PK is necessary, if there is not, MySQL will add a hidden one
    • clustered index, that is, the indexes and data are stored in the same file, and they sorted by PK
      • called “index-organized table” in Oracle
      • the data themselves are ordered by PK and the second index (if exists) stores PK instead of row offset
      • PK can be looked up very fast since it only takes one query to fetch the data instead of two queries
      • the efficiency of the second index is worse than the one of PK (while in MyISAM, PK has equivalent efficiency as INDEX)
      • updating PK is slow

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...