0拷贝

作者: 半山腰烤苞米 | 来源:发表于2022-05-08 13:01 被阅读0次

    传统 IO

    传统 IO 执行的话需要 4 次上下文切换(用户态 -> 内核态 -> 用户态 -> 内核态 -> 用户态)和 4 次拷贝(磁盘文件 DMA 拷贝到内核缓冲区,内核缓冲区 CPU 拷贝到用户缓冲区,用户缓冲区 CPU 拷贝到 Socket 缓冲区,Socket 缓冲区 DMA 拷贝到协议引擎)。

    mmap

    mmap 将磁盘文件映射到内存,支持读和写,对内存的操作会反映在磁盘文件上,适合小数据量读写,需要 4 次上下文切换(用户态 -> 内核态 -> 用户态 -> 内核态 -> 用户态)和3 次拷贝(磁盘文件DMA拷贝到内核缓冲区,内核缓冲区 CPU 拷贝到 Socket 缓冲区,Socket 缓冲区 DMA 拷贝到协议引擎)。

    RocketMQ 中就是使用的 mmap 来提升磁盘文件的读写性能。

    sendfile

    sendfile+DMA scatter/gather实现的零拷贝

    sendfile 是将读到内核空间的数据,转到 socket buffer,进行网络发送,适合大文件传输,只需要 2 次上下文切换(用户态 -> 内核态 -> 用户态)和 2 次拷贝(磁盘文件 DMA 拷贝到内核缓冲区,内核缓冲区 DMA 拷贝到协议引擎)。

    Kafka 和 Tomcat 内部使用就是 sendFile 这种零拷贝。

    总结:

    1.传统I/O

    硬盘—>内核缓冲区—>用户缓冲区—>内核socket缓冲区—>协议引擎

    2.sendfile

    硬盘—>内核缓冲区—>内核socket缓冲区—>协议引擎

    3.sendfile( DMA 收集拷贝)

    硬盘—>内核缓冲区—>协议引擎

    相关文章

      网友评论

          本文标题:0拷贝

          本文链接:https://www.haomeiwen.com/subject/paqayrtx.html