開發多執行緒程式時應注意的小細節
最近多核心處理器已成為主流,且多執行緒的程式也隨之出現。使用多執行緒的方式來開發應用程式,無非就是想利用多核心處理器來加快處理時間。可是一個設計不良的多執行緒程式,執行起來的效能可能比單執行緒程式來得差。所以在設計多執行緒程式時,有些細節也是要多加注意的。
當然,在開發多執行緒程式時,一些基本的常識是一定要知道的。像是死結(Dead Lock)、同步(Synchronization)、競速(Racing)、挨餓(Starving)、執行緒佇池(ThreadPool)等。
其它還應該注意的細節則有以下幾項。
在使用ThreadPool時,大家一定都認為先放到工作佇列中的工作就該優先派送給執行緒來執行。這樣當然是符合了公平的原則。可是這種方式會是最有效率的嗎?這可不一定了。有可能第一件工作所需的資料,跟最後一件工作所需的資料不想關。而第一件工作跟第二件工作所需的資料類似,也就是它們可能因為同步的需要而造成第二件工作會等第一件工作執行後才能執行。這種情況下,如果能安排第一件工作跟最後一件工作一起執行的話,那可能會更有效率些。
在同步的議題上,需注意的是有些在單核心處理器上使用的同步物件,在多核心處理器上可能效率上會打折扣。所以在這種同步物件的選用上也要格外留意。
有些系統的記憶體儲存方式是需階層式的方式來儲存及管理的。這表示要存取較遠階層的記憶體的話,會需要花費更多的時間。所以在程式設計上也要考量這點。
有時某種效能上的校調可能會造成反效果。例如在多核心處理上的某種演算法,用在單核心處理器上可能就沒那麼好。針對CPU的使用率上,在單核心處理器中用滿CPU的使用率可能是不錯的方式,可是在多核心處理器上則可能不是那麼好的方式。
有時在校調時,可能會受到同一部電腦中同時執行的其它程式的影響。例如在跟A程式一起執行時,可能用某種調整的結果執行起來會比較有效率;可是在跟其它程式一起執行時就不好了。
要使用多少個執行緒也是沒有一個定論。這都是要經過測試才能得知的結果。
在將程式改成多執行緒的並行運算時,也是要小心。有些原本連續性運算的結果,在變成並行運算時,可能要自己針對運算後的結果來重組,這可能也是一個Bug的來源。所以在處理上也是要特別注意的。
當然,在開發多執行緒程式時,一些基本的常識是一定要知道的。像是死結(Dead Lock)、同步(Synchronization)、競速(Racing)、挨餓(Starving)、執行緒佇池(ThreadPool)等。
其它還應該注意的細節則有以下幾項。
公平 V.S. 效率 (Fairness & Performance)
在使用ThreadPool時,大家一定都認為先放到工作佇列中的工作就該優先派送給執行緒來執行。這樣當然是符合了公平的原則。可是這種方式會是最有效率的嗎?這可不一定了。有可能第一件工作所需的資料,跟最後一件工作所需的資料不想關。而第一件工作跟第二件工作所需的資料類似,也就是它們可能因為同步的需要而造成第二件工作會等第一件工作執行後才能執行。這種情況下,如果能安排第一件工作跟最後一件工作一起執行的話,那可能會更有效率些。
同步(Synchronization)
在同步的議題上,需注意的是有些在單核心處理器上使用的同步物件,在多核心處理器上可能效率上會打折扣。所以在這種同步物件的選用上也要格外留意。
記憶體階層(Memory Hierarchy)
有些系統的記憶體儲存方式是需階層式的方式來儲存及管理的。這表示要存取較遠階層的記憶體的話,會需要花費更多的時間。所以在程式設計上也要考量這點。
小心調整(Dangeous Tuning)
有時某種效能上的校調可能會造成反效果。例如在多核心處理上的某種演算法,用在單核心處理器上可能就沒那麼好。針對CPU的使用率上,在單核心處理器中用滿CPU的使用率可能是不錯的方式,可是在多核心處理器上則可能不是那麼好的方式。
雜訊(Noise)
有時在校調時,可能會受到同一部電腦中同時執行的其它程式的影響。例如在跟A程式一起執行時,可能用某種調整的結果執行起來會比較有效率;可是在跟其它程式一起執行時就不好了。
執行緒數目(Currency Level)
要使用多少個執行緒也是沒有一個定論。這都是要經過測試才能得知的結果。
並行運算(Parallelism)
在將程式改成多執行緒的並行運算時,也是要小心。有些原本連續性運算的結果,在變成並行運算時,可能要自己針對運算後的結果來重組,這可能也是一個Bug的來源。所以在處理上也是要特別注意的。
留言
張貼留言