2010-10-14 158 views
4

我們必須使我們的系統具有高度可擴展性,並且已經針對使用VC++的Windows平臺開發。說起初,我們想同時處理100個請求(來自msmq)。最好的方法是什麼?單線程100線程或2線程50-50線程?在第二種方法的情況下,除了過程記憶之外還有什麼收益。在Windows中首先將CPU時間分配給進程,然後在該進程的線程之間進行拆分,或者OS對每個進程的線程數進行計數並根據線程而不是進程分配CPU。我們注意到,在第一種情況下,CPU利用率是15-25%,我們想要消耗更多的CPU。請記住,我們希望獲得最佳性能,因此100個請求只是例如。我們也注意到,如果我們增加120以上進程的線程數,由於上下文切換性能下降。Windows,多進程vs多線程

還有一點;我們的產品已經支持羣集,但我們希望在單個節點上使用更多的CPU。

任何建議將不勝感激。

回答

3

windows上的標準方法是多線程。並不是說這總是你最好的解決方案,但是每個線程或過程都需要支付一定的代價,而在Windows系統上,過程更加昂貴。至於調度程序,我不確定,但您可以設置進程和線程的優先級。線程的真正益處是它們的共享地址空間和無需IPC的通信能力,但是必須小心保持同步。

如果你的系統已經開發出來了,它似乎更容易實現一個多進程解決方案,特別是如果有可能使用後者多於一臺機器。由於一臺機器上的2個進程的IPC可在一般情況下擴展到多臺機器。大部分並行化嘗試都失敗了,因爲整個系統沒有對瓶頸進行評估。例如,如果你實現了100個線程,所有的線程都寫入同一個數據庫,那麼在實際性能上可能會獲得很少的收益,只需等待數據庫即可。

只是我的.02

+1

是的,我們已經面對它。數據庫是主要的瓶頸。不要冒犯任何人,但是與sql服務器相比,我們的oracle性能要好得多。但在我們這個地區,我們大部分的客戶都堅持使用sql server(價格便宜),這對我們來說是一個瓶頸。 – 2010-10-15 07:53:52

3

您無法處理比CPU核心更多的請求。 「快速」可擴展解決方案涉及設置線程池,其中活動(未在IO上阻塞)線程數量== CPU內核數量。所以創建100個線程,因爲你想要服務100 msmq請求是不好的設計。

Windows有一個線程池機制,稱爲IO Completion Ports。因爲在多進程設計中,每個進程都有自己獨立管理的IO完成端口線程池,因此您可以獲得更多的線程爭用用於CPU內核。

IO完成端口的「核心」思想是它的內核模式隊列 - 您可以手動將事件發佈到隊列中,或者通過將文件(文件,套接字,管道)關聯到文件系統來自動發佈異步IO完成與端口一起處理。另一方面,IO完成端口機制會自動將事件等待到等待的工作線程上 - 但是如果它檢測到線程池中當前「活動」線程> = CPU核心數量,它不會使作業退出隊列。

使用IO完成端口可能潛在地增加服務的可擴展性,但通常情況下,增益遠小於預期,因爲當所有CPU核心爭用服務其他資源時,其他因素會迅速發揮作用。

如果你的服務是用C++開發的,你可能會發現對堆的序列化訪問是一個很大的性能減去 - 雖然Windows版本6.1似乎已經實現了低爭用堆,所以這可能不是一個問題。

總結 - 理論上你最大的性能提升是使用在一個單一的過程管理線程池的設計。但是,你嚴重依賴於你正在使用的庫,不能序列化對關鍵資源的訪問,這些資源很快就會失去理論上的性能收益。 如果你有庫代碼序列化的很好threadpooled服務(如對象創建&破壞C++的情況下被序列化,因爲堆爭用的),那麼你需要你的圖書館/開關的使用來改變圖書館的低爭版本或者只是擴展到多個進程。

要知道的唯一方法是編寫測試用例,以各種方式強調服務器並測量結果。

+0

我一定會寫測試用例。但我想知道如何在windows窗體理論上完成cpu調度。這可以幫助我分析測試 – 2010-10-15 07:50:55

+0

只是添加一個點,我們正在使用VS2008,我猜測它使用6.1 sdk。我怎麼能證實這一點? – 2010-10-15 07:57:24

+0

您開發的SDK的版本並不重要 - 升級服務器後,「Windows 7」堆(Windows版本6.1)的性能提升會自動進行。 – 2010-10-15 08:24:45