轉:https://blog.csdn.net/zhouhao88410234/article/details/77574689?fps=1&locationNum=9
為何要懂零拷貝原理?因為rocketmq存儲核心使用的就是零拷貝原理。
- io讀寫的方式
- 中斷
- DMA
- 中斷方式
- 中斷方式的流程圖如下:
- 用戶進程發起數據讀取請求
- 系統調度為該進程分配cpu
- cpu向io控制器(ide,scsi)發送io請求
- 用戶進程等待io完成,讓出cpu
- 系統調度cpu執行其他任務
- 數據寫入至io控制器的緩沖寄存器
- 緩沖寄存器滿了向cpu發出中斷信號
- cpu讀取數據至內存
- 缺點:中斷次數取決於緩沖寄存器的大小
- 中斷方式的流程圖如下:
- DMA : 直接內存存取
- DMA方式的流程圖如下:
- 用戶進程發起數據讀取請求
- 系統調度為該進程分配cpu
- cpu向DMA發送io請求
- 用戶進程等待io完成,讓出cpu
- 系統調度cpu執行其他任務
- 數據寫入至io控制器的緩沖寄存器
- DMA不斷獲取緩沖寄存器中的數據(需要cpu時鍾)
- 傳輸至內存(需要cpu時鍾)
- 所需的全部數據獲取完畢后向cpu發出中斷信號
- 優點:減少cpu中斷次數,不用cpu拷貝數據
- DMA方式的流程圖如下:
- 數據拷貝
- 下面展示了 傳統方式讀取數據后並通過網絡發送 所發生的數據拷貝:
- 一個read系統調用后,DMA執行了一次數據拷貝,從磁盤到內核空間
- read結束后,發生第二次數據拷貝,由cpu將數據從內核空間拷貝至用戶空間
- send系統調用,cpu發生第三次數據拷貝,由cpu將數據從用戶空間拷貝至內核空間(socket緩沖區)
- send系統調用結束后,DMA執行第四次數據拷貝,將數據從內核拷貝至協議引擎
- 另外,這四個過程中,每個過程都發生一次上下文切換
- 內存緩沖數據,主要是為了提高性能,內核可以預讀部分數據,當所需數據小於內存緩沖區大小時,將極大的提高性能。
- 零拷貝是為了消除這個過程中冗余的拷貝
- 下面展示了 傳統方式讀取數據后並通過網絡發送 所發生的數據拷貝:
- 零拷貝-sendfile 對應到java中
為FileChannel.transferTo(long position, long count, WritableByteChannel target)//將數據從文件通道傳輸到了給定的可寫字節通道- 避免了第2,3步的數據拷貝,參考下圖:
- DMA從拷貝至內核緩沖區
- cpu將數據從內核緩沖區拷貝至內核空間(socket緩沖區)
- DMA將數據從內核拷貝至協議引擎
- 這三個過程中共發生2次上下文切換,分別為發起讀取文件和發送數據
- 以上過程發生了三次數據拷貝,其中有一次為cpu完成
- linux內核2.4以后,socket緩沖區做了調整,DMA帶收集功能,如下圖:
- DMA從拷貝至內核緩沖區
- 將數據的位置和長度的信息的描述符增加至內核空間(socket緩沖區)
- DMA將數據從內核拷貝至協議引擎
所謂零拷貝,指的是應用內存與內核內存不存在拷貝。對應零拷貝技術有mmap及sendfile
- 避免了第2,3步的數據拷貝,參考下圖: