zoukankan      html  css  js  c++  java
  • 【从NIO到Netty】6.零拷贝介绍

    本篇随笔有许多细节尚不明确(比如DMA和mmap以及sendfile的原理),因此仅供参考和简单理解使用,但是后面会不断补充和修正完善

    基本介绍

    1. 零拷贝是网络编程的关键,很多性能优化离不开它;

    2. 在Java程序中,常用的零拷贝有mmap(内存映射)和sendfile

    以一个简单IO读写程序介绍其中存在的问题

    package org.scaventz.nio.mine;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class ZeroCPY {
        public static void main(String[] args) throws IOException {
            File file = new File("D:/test.txt");
            RandomAccessFile raf = new RandomAccessFile(file, "rw");
            byte[] bytes = new byte[(int) file.length()];
            raf.read(bytes);
    
            // 将读到的数据写给客户端
            Socket socket = new ServerSocket().accept();
            socket.getOutputStream().write(bytes);
        }
    }

     对上面代码数据拷贝过程的分析:

    1. 【DMA copy】:通过DMA(Direct Memory Access)将数据从Hard Drive拷贝到【内核空间】Kernel buffer,DMA拷贝时不需要CPU参与运算

    2. 【CPU copy】:将数据从【内核空间】kernel buffer拷贝到【用户空间】的user buffer

    3. 【CPU copy】:将数据从【用户空间】的user buffer拷贝到【内核空间】的socket buffer

    4. 【DMA copy】:将数据从【内核空间】的socket buffer拷贝到protocol engine

    性能:所以传统的网络IO,经过了

    • 2次CPU copy + 2次 DMA copy
    • 2次切换(不算开始时进入内核态那一次)

     

    mmap 优化

    mmp通过内存映射,将文件映射到内核缓冲区,同时,用户空间可以共享内核空间的数据(对应于下图的shared)。这样,在进行网络传输时,就可以减少内核空间到用户空间的拷贝

     

    性能:

    • 1次CPU copy + 2次DMA copy
    • 2次上下文切换(存疑,待详细了解mmap原理细节后再回来订正

    sendFile优化(Linux 内核 2.1版本)


    Linux2.1版本提供了sendFile函数,数据根本不经过用户态,直接从内核缓冲区进入到Socket Buffer,同时由于和用户态完全无关,就减少了一次上下文切换。
    示意图如下


    性能:
    1. 还是存在1次CPU copy和2次DMA copy(DMA无可避免,0拷贝指无CPU拷贝)
    2. 不存在上下文切换

    sendFile优化(Linux 内核 2.4版本)
    Linux在2.4版本做了一些优化,避免了从内核缓冲区拷贝到socket buffer的操作,直接从kernel buffer拷贝到协议栈,从而再一次减少了数据拷贝
    示意图如下

    性能:

    • 几乎0 CPU copy,仍然有一些length,offset等少量数据设计到拷贝到socket buffer,但是拷贝的信息很少,消耗很低,可以忽略。
    • 2次DMA拷贝
    • 不存在上下文切换
  • 相关阅读:
    Schema约束
    gitalk报错问题
    SQL语句中单引号、双引号和反引号的区分
    用Eclipse上传项目到github
    git服务器搭建
    使用IntelliJ IDEA和Eclipse导入Github项目
    事务隔离级别的简单理解
    大公司里怎样开发和部署前端代码?
    页面无刷新Upload File
    MVC 文件上传问题
  • 原文地址:https://www.cnblogs.com/heben/p/13199426.html
Copyright © 2011-2022 走看看