『面试问答』:什么是零拷贝?

面试官 : 请说一下,什么是零拷贝?

零拷贝是指计算机执行IO操作时,CPU不需要将数据从一个存储区域复制到另一个存储区域,从而减少上下文切换以及数据拷贝的时间。零拷贝是一种IO操作优化技术,它并不是真的没有数据拷贝,而是广义上讲的减少和避免不必要的数据拷贝。

以读取一个文件并通过socket发送文件数据为例,一般需要read和write两个系统调用:

这种传统的IO读写流程,需要4次用户态和内核态的上下文切换和4次数据拷贝,这些额外的上下文切换和数据拷贝,会消耗大量的CPU资源和内存带宽,降低数据传输的效率。

零拷贝减少了上下文切换和内存拷贝的次数,主要实现方式有四种:

1 mmap

read系统调用会把内核缓冲区的数据拷贝到用户缓冲区里,为了减少这一开销,我们可以用 mmap 替换 read 。mmap直接把内核缓冲区里的数据映射到用户空间,这样内核与用户空间就不需要再进行任何的数据拷贝操作。

mmap+write方式发生了四次上下文切换以及三次数据拷贝,相对传统的IO方式,减少了一次CPU数据拷贝。

2 sendfile

sendfile是一个专门发送文件的系统调用函数,适用于将数据从文件拷贝到 socket 套接字上,使用sendfile需要硬件的支持。

通过sendfile传输文件,只需要两次上下文切换和两次DMA数据拷贝,相对传统的IO方式,sendfile去除了CPU拷贝,提升了系统性能。

3、splice

splice不需要硬件支持,可以在内核空间的读缓冲区和网络缓冲区之间建立管道,从而避免了两者之间的 CPU 拷贝操作。splice可以用于源文件描述符和目的文件描述符都是socket的情况。splice使用了 Linux 的管道缓冲机制,可以在任意两个文件描述符间传输数据,但是两个文件描述符中必须有一个是管道。

4、tee

tee与splice类似,但两个文件描述符都必须是管道。tee是两个描述符之间进行数据复制,不会消耗数据,因此源文件描述符上的数据仍然可以用于后续的读操作。

在很多开源项目中,比如Kafka 、 Nginx、RocketMQ等, 都有使用零拷贝技术。

#晒一晒我的offer##软件开发薪资爆料##我的实习求职记录##23届找工作求助阵地#
软件开发面试问答 文章被收录于专栏

分享软件开发岗位面试题及答案

全部评论

相关推荐

zzzilik:四个月实习做了3个项目不觉得很假吗,真没必要写这么多吧我感觉挑点核心的重点写一下我感觉会好点
你的简历改到第几版了
点赞 评论 收藏
分享
评论
2
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务