您的位置:首页 > 运维架构 > Linux

从Linux零拷贝说起

2019-08-04 20:32 2361 查看

数据拷贝

传统的 Linux 系统的标准 I/O 接口(read、write)是基于数据拷贝的。

也就是数据都是 copy_to_user 或者 copy_from_user,这样做的好处是,通过中间缓存的机制,减少磁盘 I/O 的操作,但是坏处也很明显,大量数据的拷贝,用户态和内核态的频繁切换,会消耗大量的 CPU 资源,严重影响数据传输的性能,有数据表明,在Linux内核协议栈中,这个拷贝的耗时甚至占到了数据包整个处理流程的57.1%。

零拷贝

零拷贝就是这个问题的一个解决方案,通过尽量避免拷贝操作来缓解 CPU 的压力。

Linux 下常见的零拷贝技术可以分为两大类:

  • 一是针对特定场景,去掉不必要的拷贝;
  • 二是去优化整个拷贝的过程。

由此看来,零拷贝并没有真正做到“0”拷贝,它更多是一种思想,很多的零拷贝技术都是基于这个思想去做的优化。

零拷贝的几种方式

原始数据拷贝操作

Linux 原始的数据拷贝操作是怎样的。假如一个应用需要从某个磁盘文件中读取内容通过网络发出去,像这样:

while((n = read(diskfd, buf, BUF_SIZE)) > 0)

write(sockfd, buf , n);

那么整个过程就需要经历:

  • 1)read 将数据从磁盘文件通过 DMA 等方式拷贝到内核开辟的缓冲区;
  • 2)数据从内核缓冲区复制到用户态缓冲区;
  • 3)write 将数据从用户态缓冲区复制到内核协议栈开辟的 socket 缓冲区;
  • 4)数据从 socket 缓冲区通过 DMA 拷贝到网卡上发出去。

整个过程发生了至少四次数据拷贝,其中两次是 DMA 与硬件通讯来完成,CPU 不直接参与,去掉这两次,仍然有两次 CPU 数据拷贝操作。

方法一:用户态直接 I/O

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux