零拷贝总结

零拷贝主要关注两个核心点:线程上下文切换次数数据在内存中被拷贝的次数

因为线程上下文切换和在内存中拷贝数据,这两种操作都很耗CPU时间,所以要提升效率,就要尽量减少这两种操作。

一、原始阶段(上图左):

最符合直觉的方式。
整个过程公发生:2次内存数据拷贝,4次线程上下文切换。

二、MMAP + write阶段(上图右):

在用户态和内核态间开辟了一块共享内存,从磁盘传输到内核态的数据就放在这块共享缓冲区上,用户缓冲区也可以共享地访问,省去了内核缓冲区到用户缓冲区的拷贝过程。
最后用户线程再发起内核调用write,将共享缓冲区的数据拷贝到socket缓冲区,供网卡读取。
整个过程公发生:1次内存数据拷贝,4次线程上下文切换。

三、sendfile阶段(上图左):

用户线程发起sendfile系统调用,此过程将内存缓冲区到用户缓冲区的拷贝过程剔除;
直接将数据从内核缓冲区拷贝到socket缓冲区,然后线程再切回到用户态。

整个过程公发生:1次内存数据拷贝,2次线程上下文切换。

四、sendfile + DMA收集阶段(上图右):

与上一阶段类似,用户线程发起sendfile系统调用,此过程也将内存缓冲区到用户缓冲区的拷贝过程剔除;
但不直接将数据从内核缓冲区拷贝到socket缓冲区,而是将数据在内核缓冲区中的地址和数据长度拷贝到socket缓冲区;
网卡读到socket缓冲区中的地址,发现数据不在socket缓冲区中,就让DMA直接去内存缓冲区中读数据。
最后线程再切回到用户态。
整个过程公发生:0次内存数据拷贝,2次线程上下文切换。

五、最后,数据从磁盘读,然后从网卡发,这种传输,涉及硬件交互;必须要在内核的控制下才能进行,所以必须要传输到内核空间,不能在硬件间直接传递。

posted @ 2023-04-23 11:53  JaxYoun  阅读(18)  评论(0编辑  收藏  举报