在軍情緊急的昨天 (2009/6/27), 本來是要幫忙解 HDMI 的 bug. 但是事件卻如雪片般地飛來~~~ 前線的 Dylan 說我 build 給他的版本有問題; Mike 多次打電話來關切; 老婆中午叫我回去教做人做事的道理, 晚上叫我教女兒英文. 另外我們的 SPDIF 規格版本太舊了, 我還得抽空上網去買新版的 SPDIF spec. 再 download 下來給 Irene 看.
然而, 真正叫人喪氣的就是: Cygwin 變得超超慢, build 一個版本似乎要好幾個小時. 我想 Dylan 應該也快要瘋了~~~ 為了測底消滅這個問題, 我趁 make code 的時候, 整理 Cygwin 變慢的原因如下:
根據網路搜尋的結果, 在 Cygwin 的官網這樣解釋:
4.2. |
Why is Cygwin suddenly so slow? |
If you recently upgraded and suddenly every command takes a very long time, then something is probably attempting to access a network share. You may have the obsolete Using //c (for C:) doesn’t work anymore. (Similarly for any drive letter, e.g. |
在討論串裡面, 有類似的說明:
http://www.mail-archive.com/cygwin@cygwin.com/msg85049.html
另外一個原因好像是 Windows 2000 的 hotfix Q8114993 改了 winsock 的處理方式.
www.cygwin.com/ml/cygwin/2003-05/msg00065.html
既然我的 cygwin 本來是快的, 原因很可能出在 Windows 的 upgrade. 可惜看來看去, 網路上說的 hotfix 竟然是 2003 年的事了, 現在的這些 hotfix 並不知道要懷疑誰好? (其中 IE 8 那一包至為可疑…, 我的 notebook 灌了它之後很會當!)
再回頭看看 Cygwin 的另外一個官網 http://cygwin.com/, 裡面提到了一些實際可行的做法. 整理如下:
1. 給 Cygwin 更多的記憶體. 這個例子可以給到 1024MB, 當然, 這是指 virtual memory. 只要 Windows 的分頁記憶體比它還大就可以了.
regtool -i set /HKLM/Software/Cygnus\ Solutions/Cygwin/heap_chunk_in_mb 1024
regtool -v list /HKLM/Software/Cygnus\ Solutions/Cygwin
執行結果如下:
mounts v2\ (Cygwin)
Program Options\ (cygnus)
heap_chunk_in_mb (REG_DWORD) = 0x00000400 (1024)
2. 用 strace 跑一次 make, 從這裡可以看到很多時間花在找 path, 因此把 cygwin 的目錄往前移. 修改的地方自然是在控制台 → 系統 → 進階 → 環境變數那裡.
此外, 我也看到一個令人心痛的事實, Cygwin 花了很多時間在確認執行檔的名稱. 它先找執行檔 XXX, 再依序找 XXX.exe, XXX.lnk, 和 XXX.exe.lnk. 原來我浪費了這麼多時間在做沒意義的傻事!
78 373674 [main] rsdk-elf-gcc 2440 mount_info::conv_to_win32_path: src_path /rsc/ct_wu/rsdk/release/rsdk-1.4.2/cygwin/newlib/rlx-elf/lib/specs, dst g:\cygwin\rsc\ct_wu\rsdk\release\rsdk-1.4.2\cygwin\newlib\rlx-elf\lib\specs, flags 0xA, rc 0
127 373801 [main] rsdk-elf-gcc 2440 symlink_info::check: GetFileAttributes (g:\cygwin\rsc\ct_wu\rsdk\release\rsdk-1.4.2\cygwin\newlib\rlx-elf\lib\specs) failed
83 373884 [main] rsdk-elf-gcc 2440 geterrno_from_win_error: windows error 3 == errno 2
116 374000 [main] rsdk-elf-gcc 2440 symlink_info::check: GetFileAttributes (g:\cygwin\rsc\ct_wu\rsdk\release\rsdk-1.4.2\cygwin\newlib\rlx-elf\lib\specs.exe) failed
81 374081 [main] rsdk-elf-gcc 2440 geterrno_from_win_error: windows error 3 == errno 2
117 374198 [main] rsdk-elf-gcc 2440 symlink_info::check: GetFileAttributes (g:\cygwin\rsc\ct_wu\rsdk\release\rsdk-1.4.2\cygwin\newlib\rlx-elf\lib\specs.lnk) failed
80 374278 [main] rsdk-elf-gcc 2440 geterrno_from_win_error: windows error 3 == errno 2
117 374395 [main] rsdk-elf-gcc 2440 symlink_info::check: GetFileAttributes (g:\cygwin\rsc\ct_wu\rsdk\release\rsdk-1.4.2\cygwin\newlib\rlx-elf\lib\specs.exe.lnk) failed
83 374478 [main] rsdk-elf-gcc 2440 geterrno_from_win_error: windows error 3 == errno 2
79 374557 [main] rsdk-elf-gcc 2440 symlink_info::check: 0 = symlink.check (g:\cygwin\rsc\ct_wu\rsdk\release\rsdk-1.4.2\cygwin\newlib\rlx-elf\lib\specs, 0x22C450) (0xA)
82 374639 [main] rsdk-elf-gcc 2440 mount_info::conv_to_win32_path: conv_to_win32_path (/rsc/ct_wu/rsdk/release/rsdk-1.4.2/cygwin/newlib/rlx-elf/lib)
在 strace 裡面看到做最久的一步是 entering. 換個目錄需要很長很長的時間. 因此我想到第三步: 硬碟重組!
3. 把硬碟重新整理一下, 執行重組! 既然 Cygwin 編譯時 CPU time 是如此地少, 可見得它是 IO bound. 此時 Memory 已經給很多了, 實際上用到的記憶體 800MB 都還不到實體記憶體 1GB 的 90%, 所以可以排除 memory bound 的可能.
4. 把防毒軟體的沒用的檢查關掉一點. 把安全的檔案夾都放到 exception 裡面.
5. 把 bash.exe 的 priority 從工作管理員裡面調升到 "標準以上". 不過, 我給 Dylan 的版本就是在調升 priority 以後 make 的, 我現在不是很敢動它. 尤其是調到 "即時" 等級的話, 根本就不能 make clean 再 make all 了.
用了這幾招之後, 感覺似乎有快一點. 至少 make 一次的時間可以在 5 分鐘以內了. 不知道是不是有 bug, 哈! 其中最好的一招好像是 3: 硬碟重組. 有人知道更厲害的絕招可以教我嗎?