异构计算关键技术之mmap(二)

异构计算关键技术之mmap(二)

一、背景

最近在设计异构低时延交易系统,在调研新技术的时候,发现了mmap+dma的设计架构。

二、简介

1. mmap技术

mmap技术是一种文件或其他对象映射到内存的技术。这种技术,让用户程序(用户空间)直接访问设备内存(内核空间),相对比在用户空间和内核空间相互拷贝数据,效率更好。

系统调用:mmap()。

使得进程之间通过映射同一个普通文件(fpga实现的设备文件)实现共享内存。普通文件被映射到进程地址空间后,进程可以访问普通内存一样,进行访问,不必再调用read(),write()等操作。

2、zero-copy

零拷贝技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另外一个特定的区域。这种技术通常用于通过网络传输文件时,节省CPU周期和内存带宽

三、DMA

DMA的全称叫做直接内存存取(direct memory access),是一种允许外围设备直接访问系统主内存的机制,原来需要依赖cpu进行数据传输,现在可以交给dma控制器来做,dma控制器传输的过程中cpu可以去做其他的工作,使得效率大大提升,目前大多数的硬件设备,包括磁盘控制器、网卡、显卡以及声卡等支持DMA技术。

在DMA技术出现之前,应用程序与磁盘之间的IO操作都是通过CPU的中断完成的,如图:

在这里插入图片描述

有了DMA技术以后:

在这里插入图片描述

DMA控制器通过将数据从磁盘控制器拷贝到内核缓冲区的工作,释放了CPU。

1. 为什么要有DMA技术?

在没有DMA技术前,IO的过程是这样的:

  • CPU发出对应的指令给磁盘控制器,然后返回;
  • 磁盘控制器收到指令后,于是就开始准备数据,会把数据放入到磁盘控制器的内部缓冲区中,然后产生一个中断
  • CPU 收到中断信号后,停下手头的工作,接着把磁盘控制器的缓冲区的数据一次一个字节地读进自己的寄存器,然后再把寄存器里的数据写入到内存,而在数据传输的期间CPU无法执行其他任务的

整个数据的传输过程,都要需要CPU亲自参与搬运数据的过程,而且这个过程,CPU是不能做其他事情的。

简单的几个字符是没有问题的,但是如果用千兆网卡或者硬盘传输大量数据的时候,都用CPU来搬运,肯定忙不过来。

计算机科学家们发现了事情的严重性后,于是就发明了 DMA 技术,也就是直接内存访问(Direct Memory Access) 技术。

2. 什么是DMA技术?

什么是DMA技术?简单理解就是,在进行I/O设备和内存的数据传输的时候,数据搬运的工作全部交给DMA控制器,而 CPU 不再参与任何与数据搬运相关的事情,这样CPU就可以去处理别的事务。

在这里插入图片描述

具体过程如下:

  • 用户进程调用read方法,向操作系统发出IO请求,请求读取数据到自己的内存缓冲区中,进程进入阻塞状态;
  • 操作系统收到请求后,进一步将IO请求发送DMA,然后让CPU执行其他任务;
  • DMA 进一步将 I/O 请求发送给磁盘;
  • 磁盘收到 DMA 的 I/O 请求,把数据从磁盘读取到磁盘控制器的缓冲区中,当磁盘控制器的缓冲区被读满后,向 DMA 发起中断信号,告知自己缓冲区已满;
  • DMA 收到磁盘的信号,将磁盘控制器缓冲区中的数据拷贝到内核缓冲区中,此时不占用 CPU,CPU 可以执行其他任务;
  • 当 DMA 读取了足够多的数据,就会发送中断信号给 CPU;
  • CPU 收到 DMA 的信号,知道数据已经准备好,于是将数据从内核拷贝到用户空间,系统调用返回;

可以看到,整个传输的过程中,cpu不再参与数据搬运的工作,而是全程由DMA完成,但是cpu在这个过程中也是必不可少的,因为传什么数据(data),传到哪里去(dst addr),都需要cpu来告诉DMA控制器。

3. 传统的文件传输有多糟糕?

如果服务端要提供文件传输的功能,我们能想到的最简单的方式是:将磁盘上的文件读取出来,然后通过网络协议发送给客户端。

传统 I/O 的工作方式是,数据读取和写入是从用户空间到内核空间来回复制,而内核空间的数据是通过操作系统层面的I/O接口从磁盘读取或写入。

代码如下:

    read(file, tmp_buf, len);
    write(socket, tmp_buf, len);

代码很简单,虽然两行代码,但是里面发生了不少的事情:

在这里插入图片描述

首先,期间共发生了4次用户态与内核态的上下文切换,因为发生了两次系统调用,一次是read()、一次是write(),每次系统调用都得先从用户态切换到内核态,等内核完成任务后,再从内核态切换到用户态。

上下文切换到成本并不小,一次切换需要耗时几十纳秒到几微秒,虽然时间看上去很短,但是在高并发的场景下,这类时间容易被累积和放大,从而影响系统的性能。

其次,还发生了4次数据拷贝,其中两次是DMA的拷贝,另外两次是CPU的拷贝:

1. 第一次拷贝:把磁盘的数据拷贝到操作系统的内核的缓冲区,这个拷贝的过程是通过DMA搬运的;

2. 第二次拷贝:把内核缓冲区的数据拷贝到用户的缓冲区里,于是我们应用程序就可以使用这部分数据了,这个拷贝是由CPU完成的;

3. 第三次拷贝:把刚才拷贝到用户的缓冲区里的数据,再拷贝到内核的socket的缓冲区里,这个过程依然是CPU搬运的;

4. 第四次拷贝:把内核的socket缓冲区的数据,拷贝到网卡的缓冲区里,这个过程由DMA搬运的;

我们回头看这个文件传输的过程,我们只是搬运一份数据,结果却搬运了4次,过多的数据拷贝无疑会消耗CPU资源,大大降低了系统性能。

这种简单又传统的文件传输方式,存在冗余的上文切换和数据拷贝,在高并发系统里是非常糟糕的,多了很多不必要的开销,会严重影响系统性能。

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

4. 如何优化文件的传输性能?

如何减少“用户态和内核态上下文切换?”

读取磁盘数据的时候,之所以要发生上下文切换,这是因为用户空间没有权限操作磁盘或者网卡,内核的权限最高,这些操作设备的过程需要交由内核完成。

所以一般要通过内核去完成某些任务的时候,就需要使用操作系统提供的系统调用函数。

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

如何减少“数据拷贝”的次数?

传统的文件传输方式会历经 4 次数据拷贝,而且这里面,“从内核的读缓冲区拷贝到用户的缓冲区里,再从用户的缓冲区里拷贝到 socket 的缓冲区里”,这个过程是没有必要的。

因为文件传输的应用场景中,在用户空间我们并不会对数据“再加工”,所以数据实际上可以不用搬运到用户空间,因此用户的缓冲区是没有必要存在的

四、零拷贝

零拷贝技术是另一个系统调用,它减少了内存中用户空间和内核空间数据的拷贝过程,使得CPU的处理效率更高。

如何实现零拷贝?

  • mmap + write
  • sendfile
4.1 mmap + write

read()系统调用的过程中会把内核缓冲区的数据拷贝到用户的缓冲区,于是为了减少这一步的开销,我们可以用mmap()替换read()系统调用函数。

    buf = mmap(file, len);
    write(sockfd, buf, len);

在这里插入图片描述

具体过程如下:

  • 应用进程调用了mmap()后,DMA会把磁盘的数据拷贝到内核的缓冲区里,这样应用进程跟着操作系统内核共享这个缓冲区;应用进程可以直接读取这个缓冲区的数据了;

  • 应用进程调用write(),操作系统直接将内核缓冲区的数据拷贝到socket缓冲区中,这一切都发生在内核态,需要CPU来搬运数据;

  • 最后把内核的socket缓冲区里的数据,拷贝到网卡的缓冲区里,这个过程由DMA搬运;

通过使用mmap()来替代read(),可以减少一次数据拷贝的过程。

4.2 sendfile()

相比于mmap来说,sendfile同样减少一次CPU的拷贝,而且还减少了2次上下文切换。

在这里插入图片描述

整个过程发生了2次用户态和内核态的上下文切换和3次拷贝:

  • 用户进程通过调用sendfile()方法向操作系统发起调用,上下文从用户态向内核态;

  • DMA控制器把数据从硬盘拷贝到读缓冲区;

  • CPU将读缓冲区数据拷贝到socket缓冲区;

  • DMA控制器把数据从socket缓冲区拷贝到网卡,上下文从内核态切换到用户态,sendfile调用返回;

sendfile方法IO数据对用户空间完全不可见,所以只能适用于完全不需要用户空间处理的情况,比如静态文件服务器。

4.3 总结

所谓的零拷贝(Zero-copy)技术,因为我们没有在内存层面去拷贝数据,也就是说全程没有通过 CPU 来搬运数据,所有的数据都是通过 DMA 来进行传输的。

零拷贝技术的文件传输方式相比传统文件传输的方式,减少了2次上下文切换和数据拷贝次数,只需要 2 次上下文切换和数据拷贝次数,就可以完成文件的传输,而且 2 次的数据拷贝过程,都不需要通过 CPU,2 次都是由 DMA 来搬运。

所以,总体来看,零拷贝技术可以把文件传输的性能提高至少一倍以上。

五、未完待续

下章将继续介绍异构系统的核心知识。

欢迎关注知乎:北京不北;

欢迎+V:beijing_bubei

欢迎关注douyin:near.X (北京不北)

获得免费答疑,长期技术交流。

六、参考文献

所以,总体来看,零拷贝技术可以把文件传输的性能提高至少一倍以上。

  • 27
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北京不北

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值