传统IO过程以及零拷贝简单介绍
传统IO过程
- 整个IO过程涉及到三个部分,分别是用户缓冲区,内核缓冲区(PageCache)以及硬件。用户态CPU发起IO请求,即发起read()系统调用,随后进程阻塞,用户态切换到内核态。内核态DMA发起IO请求与硬件进行DMA拷贝到内核缓冲区中,之后内核缓冲区与用户缓冲区进行CPU拷贝,至此read()函数调用结束数据返回,唤醒阻塞进程,内核态切换到用户态。
- 写的过程涉及用户缓冲区、内核缓冲区(Socket缓冲区)、网卡设备。首先CPU发起写的IO请求,当前进程阻塞,由用户态切换到内核态,进行CPU拷贝,将用户缓冲区中的数据拷贝到Socket缓冲区中,接着DMA控制器发起DMA请求进行DMA拷贝到网卡中,拷贝完成write()函数结束返回,内核态切换到用户态。
零拷贝-kafka为什么快的原因
关键在于用MMAP()系统调用代替原来的read()系统调用,做一个映射,数据不走用户缓冲区了,减少CPU拷贝
总结
零拷贝主要是为了减少CPU拷贝,降低CPU开销,我知道的实现技术有mmap和direct buffers。
- mmap就是采用一个映射的方式将原来从内核态读取到用户态空间的数据(一次CPU拷贝)直接映射到socket buffer里面,减少一次CPU拷贝。
- Java NIO还支持直接缓冲区(Direct Buffers),这些缓冲区在堆外内存中分配,可以直接传输到网络设备。