前言
CPU COPY
- 内存的读写操作是需要CPU协调数据总线、地址总线和控制总线来完成的,因此在"拷贝"发生的时候,往往需要CPU暂停现有的处理逻辑(CPU中断)来协助内存的读写,这种数据copy的方式我们称为CPU COPY。
DMA COPY
- 直接内存访问(Direct Memory Access)简称DMA,是一种无需CPU大量中断就可以让外设与系统内存之间进行双向数据传输的硬件机制。使用DMA可以使系统CPU从实际的I/O数据传输过程中摆脱出来,从而大大提高系统的吞吐率。
- DMA方式的数据传输由DMA控制器(DMAC)控制,在传输期间,CPU可以并发的执行其他任务。当DMA结束后,DMAC通过中断通知CPU数据传输已经结束,由CPU执行相应的中断服务程序进行后续处理。
传统IO方式:
- 读取磁盘文件并进行网络发送,数据需要copy四次:
- 第一次:将磁盘文件,读取到操作系统内核缓存区(page cache)中。
- 第二次:将内核缓存区中的数据copy到应用进程的buffer(用户程序中的缓存区)中。
- 第三步:将应用进程buffer中的数据copy到socket网络发送缓存区(属于操作系统内核的缓存区);
- 第四次:将socket buffer中的数据copy到网卡,由网卡进行网络传输。
零拷贝
- 所谓的零拷贝:是指将数据从操作系统内核缓存区(page cache)直接复制到socket网络发送缓存区,而不需要经由应用程序之手,即数据在内核态和用户态之间不发生copy。
- 对 Linux 操作系统而言,零拷贝技术依赖于底层的 sendfile() 方法实现。java中零拷贝api:FileChannal.transferTo() 方法的底层实现就是 sendfile() 方法。