0拷贝

2022-05-08  本文已影响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 收集拷贝)

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

上一篇 下一篇

猜你喜欢

热点阅读