[轉載]使用非同步 I/O 大大提高應用程式的效能

feng_xin發表於2008-04-24

 

使用非同步 I/O 大大提高應用程式的效能

學習何時以及如何使用 POSIX AIO API

 

http://www.ibm.com/developerworks/cn/linux/l-async/

 

級別: 中級

M. Tim Jones (mtj@mtjones.com), 顧問工程師, Emulex

2006 9 28

Linux® 中最常用的輸入/輸出(I/O)模型是同步 I/O。在這個模型中,當請求發出之後,應用程式就會阻塞,直到請求滿足為止。這是很好的一種解決方案,因為呼叫應用程式在等待 I/O 請求完成時不需要使用任何中央處理單元(CPU)。但是在某些情況中,I/O 請求可能需要與其他程式產生交疊。可移植作業系統介面(POSIX)非同步 I/OAIO)應用程式介面(API)就提供了這種功能。在本文中,我們將對這個 API 概要進行介紹,並來了解一下如何使用它。

AIO 簡介

Linux 非同步 I/O Linux 核心中提供的一個相當新的增強。它是 2.6 版本核心的一個標準特性,但是我們在 2.4 版本核心的補丁中也可以找到它。AIO 背後的基本思想是允許程式發起很多 I/O 操作,而不用阻塞或等待任何操作完成。稍後或在接收到 I/O 操作完成的通知時,程式就可以檢索 I/O 操作的結果。

I/O 模型

在深入介紹 AIO API 之前,讓我們先來探索一下 Linux 上可以使用的不同 I/O 模型。這並不是一個詳盡的介紹,但是我們將試圖介紹最常用的一些模型來解釋它們與非同步 I/O 之間的區別。圖 1 給出了同步和非同步模型,以及阻塞和非阻塞的模型。


1. 基本 Linux I/O 模型的簡單矩陣

每個 I/O 模型都有自己的使用模式,它們對於特定的應用程式都有自己的優點。本節將簡要對其一一進行介紹。

同步阻塞 I/O

I/O 密集型與 CPU 密集型程式的比較

I/O 密集型程式所執行的 I/O 操作比執行的處理操作更多。CPU 密集型的程式所執行的處理操作比 I/O 操作更多。Linux 2.6 的排程器實際上更加偏愛 I/O 密集型的程式,因為它們通常會發起一個 I/O 操作,然後進行阻塞,這就意味著其他工作都可以在兩者之間有效地交錯進行。

最常用的一個模型是同步阻塞 I/O 模型。在這個模型中,使用者空間的應用程式執行一個系統呼叫,這會導致應用程式阻塞。這意味著應用程式會一直阻塞,直到系統呼叫完成為止(資料傳輸完成或發生錯誤)。呼叫應用程式處於一種不再消費 CPU 而只是簡單等待響應的狀態,因此從處理的角度來看,這是非常有效的。

2 給出了傳統的阻塞 I/O 模型,這也是目前應用程式中最為常用的一種模型。其行為非常容易理解,其用法對於典型的應用程式來說都非常有效。在呼叫 read 系統呼叫時,應用程式會阻塞並對核心進行上下文切換。然後會觸發讀操作,當響應返回時(從我們正在從中讀取的裝置中返回),資料就被移動到使用者空間的緩衝區中。然後應用程式就會解除阻塞(read 呼叫返回)。


2. 同步阻塞 I/O 模型的典型流程

從應用程式的角度來說,read 呼叫會延續很長時間。實際上,在核心執行讀操作和其他工作時,應用程式的確會被阻塞。

同步非阻塞 I/O

同步阻塞 I/O 的一種效率稍低的變種是同步非阻塞 I/O。在這種模型中,裝置是以非阻塞的形式開啟的。這意味著 I/O 操作不會立即完成,read 操作可能會返回一個錯誤程式碼,說明這個命令不能立即滿足(EAGAIN EWOULDBLOCK),如圖 3 所示。


3. 同步非阻塞 I/O 模型的典型流程

非阻塞的實現是 I/O 命令可能並不會立即滿足,需要應用程式呼叫許多次來等待操作完成。這可能效率不高,因為在很多情況下,當核心執行這個命令時,應用程式必須要進行忙碌等待,直到資料可用為止,或者試圖執行其他工作。正如圖 3 所示的一樣,這個方法可以引入 I/O 操作的延時,因為資料在核心中變為可用到使用者呼叫 read 返回資料之間存在一定的間隔,這會導致整體資料吞吐量的降低。

非同步阻塞 I/O

另外一個阻塞解決方案是帶有阻塞通知的非阻塞 I/O。在這種模型中,配置的是非阻塞 I/O,然後使用阻塞 select 系統呼叫來確定一個 I/O 描述符何時有操作。使 select 呼叫非常有趣的是它可以用來為多個描述符提供通知,而不僅僅為一個描述符提供通知。對於每個提示符來說,我們可以請求這個描述符可以寫資料、有讀資料可用以及是否發生錯誤的通知。


4. 非同步阻塞 I/O 模型的典型流程 (select)

select 呼叫的主要問題是它的效率不是非常高。儘管這是非同步通知使用的一種方便模型,但是對於高效能的 I/O 操作來說不建議使用。

非同步非阻塞 I/OAIO

最後,非同步非阻塞 I/O 模型是一種處理與 I/O 重疊進行的模型。讀請求會立即返回,說明 read 請求已經成功發起了。在後臺完成讀操作時,應用程式然後會執行其他處理操作。當 read 的響應到達時,就會產生一個訊號或執行一個基於執行緒的回撥函式來完成這次 I/O 處理過程。


5. 非同步非阻塞 I/O 模型的典型流程

在一個程式中為了執行多個 I/O 請求而對計算操作和 I/O 處理進行重疊處理的能力利用了處理速度與 I/O 速度之間的差異。當一個或多個 I/O 請求掛起時,CPU 可以執行其他任務;或者更為常見的是,在發起其他 I/O 的同時對已經完成的 I/O 進行操作。

下一節將深入介紹這種模型,探索這種模型使用的 API,然後展示幾個命令。

 

非同步 I/O 的動機

從前面 I/O 模型的分類中,我們可以看出 AIO 的動機。這種阻塞模型需要在 I/O 操作開始時阻塞應用程式。這意味著不可能同時重疊進行處理和 I/O 操作。同步非阻塞模型允許處理和 I/O 操作重疊進行,但是這需要應用程式根據重現的規則來檢查 I/O 操作的狀態。這樣就剩下非同步非阻塞 I/O 了,它允許處理和 I/O 操作重疊進行,包括 I/O 操作完成的通知。

除了需要阻塞之外,

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/81/viewspace-250397/,如需轉載,請註明出處,否則將追究法律責任。

相關文章