要打造一個效能良好的 Multi-Thread Application 是難度相當高的一件事,一般來說第一個會碰到的問題就是因為 synchronization objects 的 contention 造成的效能下降,通常可以用 atomic operator 及 lock-free algorithm 做一些改善。而隨著現在 CPU 的核心數愈來愈多,又把難度向上提高了不少 Orz。其它常碰到的問題包括了:
第一個是 Load imbalance:假設你的電腦是 4 cores,理想上開 4 threads 來做事是最好的,但是這 4 個 threads 要做的事情必需一樣重,不然就會有人是閒閒沒事做,別人操的要死的狀況,如果你是開發演算法,可以考慮用 Intel TBB 中的 task 來解決這個問題。
第二個是 Threading overhead:大家都知道 context switch 是很花時間的,但是並不是說 threads 愈少就一定愈好!這是一個很複雜的問題,留待之後再來討論~
第三個是 Memory Bandwidth Bottleneck:因為每個 thread 它所需要讀取/寫入的資料有可能是毫無關聯的,但因為資料及指令是需要被讀入 L1 Cache 才能執行,因此會大幅增加 cache line miss 的機率,一般來說L2 Cache 比L1 Cache慢約七倍,而 Main Memory 就更不用說了,更是無敵慢,因此這點將會是造成效能問題的最大瓶頸。老實說,這是我目前覺得最難處理的:如何讓 cache 及 memory 作最好的運用。
前面三個問題(sync obj, imbalance, overhead)比較容易解決,Intel 的工具 Thread Profiler 可以幫你很有效的分析出問題所在,下面這份教材是我目前看過最好的,如果你現在在開發 Multi-Thread Application,你一定要看一看這一篇:
http://www1.ju.edu.jo/ecourse/cpestcourse/notes/Intel/06%20Edited_ThreadProfiler.ppt
Thread Profiler 可以讓你在不需要修改程式的狀況下就進行分析,支援了目前大部份主流的 compiler,而且可以跟 source code 結合,直接指出問題的所在~你也可以拿來分析你 Synchronization Objects 的 contention 狀況, 強力推薦。
至於記憶體的問題,則是要請出神器 Vtune 來解了,我們下回再做討論~