Winsock五種I O模型的效能分析

2021-05-24 14:05:39 字數 4431 閱讀 2565

五種i/o模型的效能分析

重疊i/o模型的另外幾個優點在於,微軟針對重疊i/o模型提供了一些特有的擴充套件函式。當使用重疊i/o模型時,可以選擇使用不同的完成通知方式。

採用事件物件通知的重疊i/o模型是不可伸縮的,因為針對發出wsawaitformultipleevents呼叫的每個執行緒,該i/o模型一次最多都只能支援6 4個套接字。假如想讓這個模型同時管理不止64個套接字,必須建立額外的工作者執行緒,以便等待更多的事件物件。因為作業系統同時能夠處理的事件物件是有限的,所以基於事件物件的i/o模型不具備伸縮性。

使用完成例程通知的重疊i/o模型,因為以下幾個原因,也不是開發高效能伺服器的最佳選擇。首先,許多擴充套件功能不允許使用apc(asyncroneus procedure call,非同步過程呼叫)完成通知。其次,由於apc在系統內部特有的處理機制,應用程式執行緒可能無限等待而得不到完成通知。當乙個執行緒處於「可警告狀態」時,所有掛起的apc按照先進先出的順序(fifo)接受處理。現在考慮這樣一種情況,伺服器已經建立起了乙個連線,並且呼叫含有完成例程指標的wsarecv投遞了乙個重疊i/o請求。當有資料到達時(即i/o完成時),完成例程執行並且再次呼叫wsarecv丟擲另外乙個重疊i/o請求。乙個apc丟擲的i/o操作需要一定的時間才能完成,所以這期間可能另外乙個完成例程等待執行(比如本次wsarecv還沒接收完時,又有乙個新的客戶接入併發來資料),因為還有更多的資料需要讀取(上乙個客戶發來的資料尚未讀完)。只要(投遞wsarecv的)那個套接字上還有「未決」(未接收完)的資料,就會導致呼叫執行緒長久阻塞。

基於完成埠通知的重疊i/o模型是windows nt系統提供的乙個真正支援高伸縮性的i/o模型。在上一章中,**了winsock幾種常見的i/o模型,並且說明了當應對大規模客戶連線時,完成埠是最佳的選擇,因為它提供了最好的伸縮性。

對不同winsock i/o模型的效能測試結果如圖1所示。其中伺服器採用pentium 4 1.7 ghz xeon的cpu,768m記憶體;客戶端有3臺pc,配置分別是pentium 2 233mhz ,128 mb 記憶體,pentium 2 350 mhz,128 mb記憶體,itanium 733 mhz ,1 gb記憶體。伺服器、客戶端安裝的作業系統都是windows xp。

圖1 不同i/o模型的效能比較

1.分析圖表1提供的測試結果可知,在所用的i/o模型中,阻塞模式效能最差。這個測試程式中,伺服器為每個客戶建立兩個執行緒:乙個負責處理資料的接收,乙個負責處理資料的傳送。在多次測試中的共同問題就是,阻塞模式難以應對大規模的客戶連線,因為它在建立執行緒上耗費了太多的系統資源。因此,伺服器建立太多的執行緒後,再呼叫createthread函式時,將返回error_not_enough_memory的錯誤,這個錯誤碼提示記憶體不夠。那些發出連線請求的客戶則收到wsaeconnrefused的錯誤提示,表示連線的嘗試被拒絕。

讓我們來看看監聽函式listen,其原型如下:

winsock_api_linkage int wsaapi listen(socket s, int backlog );

引數一s已繫結了位址的監聽套接字。

引數二backlog指定了正在等待連線的最大佇列長度。

引數backdog非常重要, 因為完全可能同時出現幾個對伺服器的連線請求。例如,假定backlog引數為2時有三個客戶機同時發出連線請求,那麼前兩個會被放在乙個「等待處理」佇列中,以便應用程式依次為它們提供服務。而第三個連線的請求就會造成乙個wsaeconnrefused錯誤。一旦伺服器接受了乙個連線請求,那個連線請求就會從佇列中刪去,以便可以繼續接收其他客戶發出的連線請求。即當乙個連線請求到來時佇列已滿,那麼客戶將收到乙個wsaeconnrefused錯誤。而backlog引數本身的大小就存在著限制,這個限制是由協議提供者決定的。

故阻塞模式下,由於系統資源的限制,其併發處理量是極難突破的。

2.非阻塞模式表現出的效能要比阻塞模式稍好,但是占用了太多的cpu處理時間。測試伺服器將所有客戶對應的socket分類放到fd_set集合中,然後呼叫select函式篩選出對應集合中有事件發生的socket,並對集合更新。接下來呼叫fd_isset巨集重新判斷乙個套接字是否在原來加入的fd_set集合中。隨著客戶連線數量的增多,這種模型的侷限性逐漸凸現。僅僅為了判斷乙個套接字是否有網路事件發生,就需要對集合fd_set執行一次遍歷!使用迭代搜尋來對select更新的fd_set進行掃瞄,效能可以得到一些提公升。瓶頸在於,伺服器必須能夠很快地掃瞄出fd_set集合中的有網路事件發生的套接字的相關資訊。針對這個問題,可以使用更複雜的掃瞄演算法,如雜湊搜尋,它的效率是極高的。還需要注意的乙個問題就是,非分頁池(即直接在物理記憶體中分配的記憶體)的使用極高。這是因為afd(ancillary function driver,由afd.sys提供的支援windows sockets應用程式的底層驅動程式,其中執行在核心模式下afd.sys驅動程式主要管理winsock tcp/ip通訊)和tcp都將使用i/o快取,因為伺服器讀取資料的速度是有限的,相對於cpu的處理速度而言,i/o基本是零位元組的吞吐量。

3.基於windows訊息機制的wsaasyncselect模型能夠處理一定的客戶連線量,但是擴充套件性也不是很好。因為訊息幫浦很快就會阻塞,降低了訊息處理的速度。在幾次測試中,伺服器只能處理大約1/3的客戶端連線。過多的客戶端連線請求都將返回錯誤提示碼wsaeconnrefused,說明伺服器不能及時處理fd_accept訊息導致連線失敗,這樣監聽佇列中待處理的連線請求不致於爆滿。然而,通過上表中的資料可以發現,對那些已經建立的連線,其平均吞吐量也是極低的(即使對於那些對位元率進行了限制的客戶也如此)。

4.基於事件通知的wsaeventselect模型表現得出奇的不錯。在所有的測試中,大多數時候,伺服器基本能夠處理所有的客戶連線,並且保持著較高的資料吞吐量。這種模型的缺點是,每當有乙個新連線時,需要動態管理執行緒池,因為每個執行緒只能夠等待64個事件物件。當客戶連線量超過64個後再有新客戶接入時,需要建立新的執行緒。在最後一次測試中,建立起了超過45,000個的客戶連線後,系統響應速度變得非常緩慢。這時由於為處理大規模的客戶連線建立了大量的執行緒,占用了過多的系統資源。791個執行緒基本達到了極限,伺服器不能再接受更多的連線了,原因是wsaenobufs:無可用的緩衝區空間,套接字無法建立。另外,客戶端程式也達到了極限,不能維持已經建立的連線。

使用事件通知的重疊i/o模型和wsaeventselect模型在伸縮性上差不多。這兩種模型都依賴於等待事件通知的執行緒池,處理客戶通訊時,大量執行緒上下文的切換是它們共同的制約因素。重疊i/o模型和wsaeventselect模型的測試結果很相似,都表現得不錯,直到執行緒數量超過極限。

5.最後是針對基於完成埠通知的重疊i/o模型的效能測試,由上表中資料可以看出,它是所有i/o模型中效能最佳的。記憶體使用率(包括使用者分頁池和非分頁池)和支援的客戶連線量與基於事件通知的重疊i/o模型和wsaeventselect模型基本相同。真正不同的地方,在於對cpu的占用。完成埠模型只占用了60%的cpu,但是在維持同樣規模的連線量時,另外兩種模型(基於事件通知的重疊i/o模型和wsaeventselect模型)占用更多的cpu。完成埠的另外乙個明顯的優勢是,它維持更大的吞吐量。

對以上各種模型進行分析後,可以會發現客戶端與伺服器資料通訊機制本身存在的缺陷是乙個瓶頸。在以上測試中,伺服器被設計成只做簡單的回應,即只是將客戶端傳送過來的資料傳送回去。客戶端(即使有位元率限制)不停的傳送資料給伺服器,這導致大量資料阻塞在伺服器上與這個客戶端對應的套接字上(無論是tcp緩衝區還是afd的單套接字緩衝區,它們都是在非分頁池上)。在最後三種效能比較好的模型中,同一時間只能執行乙個接受輸入操作,這意味著在大多數時間,還是有很多資料處於「未決」狀態。可以修改伺服器程式使其以非同步方式接受資料,這樣一旦有資料達到,需要將資料快取起來。這種方案的缺點是,當乙個客戶連續傳送資料時,非同步接受到了大量的資料。這會導致其他的客戶無法接入,因為呼叫執行緒和工作者執行緒都不能處理其他的事件或完成通知。通常情況下,呼叫非阻塞非同步接收函式,先返回wsaewouldblock,然後資料間斷性的傳輸,而不採取連續接收的方式。

i/o模型的選擇

通過上一節對各種模型的測試分析,對於如何挑選最適合自己應用程式的i/o模型已經很明晰了。同開發乙個簡單的執行多執行緒的鎖定模式應用相比,其他每種i/o模型都需要更為複雜的程式設計工作。因此,針對客戶機和伺服器應用開發模型的選擇,有以下原則。

1. 客戶端

若打算開發乙個客戶機應用,令其同時管理乙個或多個套接字,那麼建議採用重疊i/o或wsaeventselect模型,以便在一定程度上提公升效能。然而,假如開發的是乙個以windows為基礎的應用程式,要進行視窗訊息的管理,那麼wsaasyncselect模型恐怕是一種最好的選擇,因為wsaasyncselect本身便是從windows訊息模型借鑑來的。採用這種模型,程式需具備訊息處理功能。

2. 伺服器端

若開發的是乙個伺服器應用,要在乙個給定的時間,同時控制多個套接字,建議採用重疊i/o模型,這同樣是從效能角度考慮的。但是,如果伺服器在任何給定的時間,都會為大量i/o請求提供服務,便應考慮使用i/o完成埠模型,從而獲得更佳的效能。

說明:

本文主要譯自《network programming for microsoft windows

》一書的6.4節《伺服器策略》。

WinSock五種I O模型的效能分析

五種i o模型的效能分析 重疊i o模型的另外幾個優點在於,微軟針對重疊i o模型提供了一些特有的擴充套件函式。當使用重疊i o模型時,可以選擇使用不同的完成通知方式。採用事件物件通知的重疊i o模型是不可伸縮的,因為針對發出wsawaitformultipleevents呼叫的每個執行緒,該i o...

Winsock五種I O模型的效能分析

五種i o模型的效能分析 重疊i o模型的另外幾個優點在於,微軟針對重疊i o模型提供了一些特有的擴充套件函式。當使用重疊i o模型時,可以選擇使用不同的完成通知方式。採用事件物件通知的重疊i o模型是不可伸縮的,因為針對發出wsawaitformultipleevents呼叫的每個執行緒,該i o...

Winsock的五種套接字I O模型之select

winsock提供了兩種套接字模式 鎖定和非鎖定.當我們使用鎖 定套接字的時候,我們使用的很多函式,例如accpet,send,recv等等,如果沒有資料需要處理,這些函式都不會返回,也就是說,你的應用程 序會阻塞在那些函式的呼叫處.而 如果使用非阻塞模式,呼叫這些函 數,不管你有沒有資料到達,他都...