2011-05-31 73 views
1

細長問題:
當具有多個阻塞線程然後CPU核心,在哪裏是通過降低上下文最大化CPU效率線量和線程塊時間之間的平衡切換開銷?線程數量和線程塊時間之間的平衡在哪裏?

我有很多種IO設備,我需要在Windows 7上使用x64多核處理器進行控制:PCI設備,網絡設備,將東西保存到硬盤驅動器,大量數據被複制, ......最常見的政策是:「在它上面放一個線索!」。幾十個線程後,這開始覺得不好主意。

我的內核都沒有被100%使用,還有幾個內核仍在閒置,但是在10到100毫秒範圍內出現延遲,這些延遲無法通過IO阻塞或CPU密集型使用來解釋。其他流程似乎也不需要資源。我懷疑上下文切換開銷。

有一堆可能的解決方案,我有:

  • 捆綁同一個IO設備減少線程:這主要無二的硬盤驅動器,但也許對於網絡也是如此。如果我在一個線程中爲硬盤節省了20MB,而在另一個線程中節省了20MB,那麼把它全部發布到相同的情況下會不會更好?如果有多個硬盤驅動器,這將如何工作?
  • 通過捆綁相似的IO設備來減少線程並提高優先級:數十個優先級提高的線程可能會讓我的用戶界面線程斷斷續續。但是我可以將所有這些功能集中在一個或幾個線程中,並增加它的優先級。

任何情況下,研究解決類似的問題,我們非常感激。

回答

3

首先,它聽起來像應該使用異步I/O(IO完成端口,優選地)來執行這些任務,而不是用單獨的線。阻塞線程通常是做I/O的錯誤方式。

其次,阻塞的線程不應該影響上下文切換。調度程序必須處理所有處於活動狀態的線程,因此,運行大量線程(未被阻止)可能會減慢上下文切換的速度。但只要你的大部分線程被阻塞,它們都不應該影響那些沒有的線程。

+0

「阻塞線程通常是做I/O的錯誤方式」爲什麼?使用線程是實現我知道的非阻塞I/O的最簡單方法。異步I/O總是有點棘手的管理。 – 2011-05-31 08:21:37

+2

@ james-kanze:但是ASIO的表現要好得多。 – 2011-05-31 08:26:33

+0

@James:因爲執行ASIO的原因通常與性能有關,並且使用線程會給你帶來非常糟糕的性能。 (我們甚至不會涉及到所有常見的線程錯誤,這些錯誤可能會讓您「陷入一些棘手的問題」:) – jalf 2011-05-31 08:32:08

0

我不認爲有一個結論性的答案,這可能取決於 您的操作系統爲好;有些處理線程比其他更好。儘管如此, 延遲在10至100ms的範圍內不是由於上下文切換本身 (儘管它們可能是由於所述調度算法 的特性)。我在Windows下的經驗是,I/O非常低效,如果你正在做任何類型的I/O,你將會阻塞。而一個進程或線程的I/O最終會阻塞其他進程 或線程。 (在Windows下,例如,有可能是在 沒有點有一個以上的線程處理的硬盤驅動器。您無法讀取或寫入 在同一時間幾個部門,我的印象是, Windows不優化訪問像其他一些系統一樣。)

至於你確切的問題:

「如果我節省20MB在一個線程中的硬盤驅動器,以及10MB的 等,豈不是更好地給它的所有張貼到相同?「:這取決於操作系統的 。通常,不應使用單獨的線程減少時間或等待時間,並且根據其他活動和操作系統, 可能是一種改進。 (如果在 實例中有多個磁盤請求,大多數操作系統將優化訪問,重新排序請求以減少磁頭移動。)最簡單的解決方案是嘗試兩種方法,即 並查看哪一個在您的系統上更好地工作。

「這將在多個硬盤驅動器的情況下如何工作?」:如果請求是不同的 驅動器,OS應 能夠並行執行I/O。

關於提高一個或多個theads的優先級,這是非常依賴操作系統 ,但可能值得嘗試。除非在具有較高優先級的線程中使用顯着的CPU時間,否則應該不會影響 用戶界面—這些線程大多被阻塞用於I/O,請記住 。

+0

「我的印象是,Windows並不像其他系統那樣優化訪問」 - 並非NCQ(本地命令隊列)的全部原因,因爲硬盤本身處於優化訪問的更好位置,因爲它由磁盤幾何驅動? Windows肯定可以支持啓用NCQ的驅動器,例如發出多次讀取並處理結果不按順序。 – MSalters 2011-05-31 09:23:26

+0

@MSalters自從我在這個級別工作以來,情況發生了變化,但仍然有各種可以使用的優化策略,這取決於硬盤驅動器(這使得系統更加困難)。事實是,在相同的硬件上運行,磁盤IO在Linux下比在Windows下快得多。 – 2011-05-31 11:12:10

+0

我覺得有趣的是,聲稱使用線程來執行「異步」I/O的人和正確的ASIO API一樣高效的人,也是基於他的基於線程的I/O體驗,推斷Windows在低效率I/O。您是否想過,問題可能是您堅持使用錯誤的工具來完成這項工作? – jalf 2011-06-02 08:19:27

1

10-100ms,某些內核處於空閒狀態:它本身並不是上下文切換開銷,因爲交換機的速度比這些延遲快幾個數量級,即使是在覈心交換和緩存刷新的情況下也是如此。

異步I/O在這裏幫不了多少忙。實現ASIO的內核線程池也必須被調度/交換,儘管這比用戶空間線程更快,因爲Wagnerian環循環較少。如果CPU負載成爲問題,我肯定會前往ASIO,但事實並非如此。

你不缺CPU,那是什麼?是不是有很多顛簸 - RAM短缺?過度的分頁肯定會導致大的延遲。你的頁面文件在哪裏?我將Drive C推到另一個快速SATA驅動器上。

PCI帶寬?那裏有幾張電視卡?

磁盤控制器沖洗活動 - 你有SSD接近容量?對於無法解釋的暫停,這總是很好的。即使我的128G SSD只有2/3滿了,我仍然可以暫停。

我從來沒有遇到過與上下文交換時間有關的問題,而且我已經寫了幾十年的多線程應用程序。 Windows操作系統日程安排&合理快速地將就緒線程分派到內核中。 '幾十個線程'本身(即不是全部運行!)不是一個遠程問題 - 現在看我的TaskManger /性能,我有1213個線程加載並且沒有任何性能問題,CPU使用率約爲6% (在後臺運行的應用程序,bitTorrent等)。火狐有30個線程,VLC媒體播放器27,我的測試應用程序23。沒有任何問題寫這篇文章。

鑑於你10-100ms延遲的問題,我會感到驚訝,如果有線程優先級擺弄和/或改變你的工作被加載到線程的方式提供任何改善 - 別的東西餡系統,(你有沒有得到了我編碼的任何驅動程序,對嗎?:)。

perfmon給出任何線索嗎?

RGDS, 馬丁

0

好了,我的Windows 7正在運行的線程950。我不認爲再增加幾十個就會產生重大影響。但是,你一定要看看線程池或其他盜用工具 - 你不應該爲了阻止它們而創建新線程。如果Windows默認提供異步I/O,則使用它。