跳转至

零拷贝技术

磁盘可以说是计算机系统最慢的硬件之一,读写速度相差内存 10 倍以上,需要优化

DMA技术

没有DMA之前,CPU必须处理完当前中断的内容才能处理其他事情。

  • 以read(),为例,中断时需要先从磁盘读到page cache,再读到用户缓存区。

  • DMA技术:在向磁盘发送IO请求时,会先发给DMA。此时CPU可以正常工作,等磁盘正式读到DMA缓存区,再发送中断信号让CPU工作--从内核拷贝到用户空间。

传统文件传输的糟糕

  • 一次read和write,要进行4次用户态与内核态上下文切换,两次系统调用,还有4次数据拷贝
    • 四次数据:磁盘到内核,内核到用户,内核到socket,socket到网卡

要想提高文件传输的性能,就需要减少「用户态与内核态的上下文切换」和「内存拷贝」的次数

思想

要想减少上下文切换到次数,就要减少系统调用的次数

如何实现零拷贝?

  • mmap +write:mmap是映射内存区,可以共享,而read是拷贝。
    • 目的:减少一次拷贝,但还不够
  • sendfile发送文件的系统调用:替代send和write
    • (Linux 2.1)两次上下文,三次拷贝,省去内核到socket。
    • (Linux 2.3)两次上下文,内核到socket,内核到网卡。

异步IO

阻塞在read读取,可以用异步IO来解决。

文件传输过程,其中第一步都是先需要先把磁盘文件数据拷贝到内核缓冲区磁盘高速缓存(PageCache

注意跟页表没关系。

思路:尽量把读写磁盘,改为读写内存 - PageCache 使用了「预读功能」。这点和高速缓存其实也比较类似 - 但是大文件不适用,会占满PageCache。

大文件传输「异步 I/O + 直接 I/O」

传统IO - 先到pageCache - 再到用户缓存区 异步IO+直接IO: 此过程绕开了pageCache。绕开 PageCache 的 I/O 叫直接 I/O - 异步IO请求 - 磁盘IO直接读到用户缓存区 - 然后read再去读进程