Linux I/O (一):Nio Is Real 'Zero-Copy'?
What Is ‘Zero-Copy’?
Zero copy refers to a collection of techniques which reduce the number of copies of blocks of data in order to make data transfer more efficient. This helps reduce the number of unnecessary memory accesses and CPU consumption, and therefore enhance overall system performance.
“零拷贝”并非字面上意思。下面以“一次网络数据包读取流程”为例,讲解什么是“零拷贝技术” ? 采用“传统方式”,需要两次DMA拷贝,两次CPU拷贝。借用“sendfile()”方式,仅需要一次内存拷贝,两次DMA拷贝。
two CPU copy two DMA copy
实例代码:
read(file, tmp_buf, len); write(socket, tmp_buf, len);
one CPU copy two DMA copy
‘Zero-Copy’ Techniques
Zero copy can be classified into two groups:
- reduce data copies between devices (disk or network card) and kernel buffers.
- reduce data copies between kernel buffers and application buffers.
DMA(Direct Memory Access): DMA allows special purpose hardware to read or write main memory without involving the CPU. which greatly reduces CPU consumption and also eliminates redundant data copies between device and kernel buffers.
Sendfile() : data are copied directly from the kernel buffer to the socket buffer. Once all data are copied into the socket buffer, the sendfile() system call will return to indicate the completion of data transfer from the kernel buffer to socket buffer. Then, data will be copied to the buffer on the network card and transferred to the network. The sendfile() method is much more efficient than the combination of read() and write(), Compared with the traditional data transmission method,which reduces the number of context switch from four to two. However, it still needs three data copies (two DMA copies and one CPU copy) to finish the data transmission.
“sendfile()” source code:
#includessize_t sendfile(int out_fd, int in_fd, off_t *offset , size_t count);
- in_fd 等待读入数据的fd.
- out_fd 等待写出数据的fd.
- offset 开始读取数据之前向前偏移的byte数.
- count 两个fd之间“搬移”的数据的byte数.
针对上层应用而言:java通过”channel.transferTo()“入口,调用底层linux的”sendfile()“方法,实现高性能数据传输。
public abstract long transferTo(long position, long count, WritableByteChannel target) throws IOException;
Channel categories:
- FileChannel
- DatagramChannel(UDP)
- SocketChannel(TCP)
- ServerSocketChannel(TCP)
- AsynchronousServerSocketChannel(TCP)
附 录
- C10K linux
- Zero Copy I: User-Mode Perspective Dragan Stancevic
- Memory Mapping and DMA Constantine Shulyupin
- psendfile python sendfile(2) benchmark