数据交互模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dqLJVb5U-1665401648551)(en-resource://database/1074:1)]
- 读数据过程:
- 应用程序要读取磁盘数据,调用 read()函数从而实现用户态切换内核态,这是第 1 次状态切换;
DMA 控制器将数据从磁盘拷贝到内核缓冲区,这是第 1 次 DMA 拷贝;
CPU 将数据从内核缓冲区复制到用户缓冲区,这是第 1 次 CPU 拷贝;
CPU 完成拷贝之后,read()函数返回实现用户态切换用户态,这是第 2 次状态切换;
- 写数据过程:
- 应用程序要向网卡写数据,调用 write()函数实现用户态切换内核态,这是第 1 次切换;
CPU 将用户缓冲区数据拷贝到内核缓冲区,这是第 1 次 CPU 拷贝;
DMA 控制器将数据从内核缓冲区复制到 socket 缓冲区,这是第 1 次 DMA 拷贝;
完成拷贝之后,write()函数返回实现内核态切换用户态,这是第 2 次切换; - 综上:
读过程涉及 2 次空间切换、1 次 DMA 拷贝、1 次 CPU 拷贝;
写过程涉及 2 次空间切换、1 次 DMA 拷贝、1 次 CPU 拷贝;
可见传统模式下,涉及多次空间切换和数据冗余拷贝,效率并不高,接下来就该零拷贝技术出场了。
注:直接内存访问(Direct Memory Access),是一种硬件设备绕开 CPU 独立直接访问内存的机制。所以 DMA 在一定程度上解放了 CPU,把之前 CPU 的杂活让硬件直接自己做了,提高了 CPU 效率。
mmap 方式
-
mmap 是 Linux 提供的一种内存映射文件的机制,它实现了将内核中读缓冲区地址与用户空间缓冲区地址进行映射,从而实现内核缓冲区与用户缓冲区的共享。
-
mmap 对大文件传输有一定优势,但是小文件可能出现碎片
-
综上:
减少了一次cpu数据拷贝,用户态与内核态的切换次数没有减少
sendfile方式
- 从用户程序的用户态切换至内核态,使用 DMA将数据读入内核缓冲区,不会使用 cpu
- 数据从内核缓冲区传输到 socket 缓冲区,cpu 会参与拷贝
- DMA 将 socket 缓冲区的数据写入网卡,不会使用 cpu
- 综上:
发生了两次状态切换,1 次 CPU 拷贝、2 次 DMA 拷贝。