---
# System prepended metadata

title: Zero Copy
tags: [Note, Zero Copy, MCL]

---

Zero Copy
===

###### tags: `Note` `MCL` `Zero Copy`


[toc]

## Zero Copy


### scenario

從 disk 讀檔，再將檔案用 socket 傳給另一 client

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

![](https://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6345/6345f1.jpg)

* cpu copy 2 次
* dma copy 2 次
* 切 mode 4 次

### mmap + write

利用 mapping 的方式減少 cpu copy

```c
tmp_buf = mmap(file, len);
write(socket, tmp_buf, len);
```

![](https://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6345/6345f2.jpg)

* cpu copy 1 次
* dma copy 2 次
* 切 mode 4 次

#### SIGBUS 問題 (非預期的記憶體存取操作)

解法:
* callback function
* file leasing (opportunistic locking)
    * 當另一個 process 嘗試 write 你正在使用的 memory 段時， kernel 會送 RT_SIGNAL_LEASE，表示無法使用，並且在 process 被 SIGBUS kill 之前中斷 write

### sendfile

直接從一個 fd copy 內容到另一個 fd

```c
sendfile(socket, file, offset, len);
```

![](https://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6345/6345f3.jpg)

* cpu copy 1 次
* dma copy 2 次
* 切 mode 2 次

### sendfile + DMA gather

只 copy 些微資訊，例如 fd, offset, len 之類的

```c
sendfile(socket, file, offset, len);
```

![](https://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6345/6345f4.jpg)

* cpu copy 0 次 (嚴格來說有 1 次，但非 copy 整份內容)
* dma copy 2 次
* 切 mode 2 次

### splice

建立 pipe buffer

```c
ssize_t splice(int fd_in, off64_t *off_in, int fd_out,
                      off64_t *off_out, size_t len, unsigned int flags);
```

![](https://aijishu.com/img/bVM8G)

* cpu copy 0 次 (嚴格來說有 2 次，但只有 copy pointer)
* dma copy 2 次
* 切 mode 6 次


## Zero Copy 應用

網路封包處理
![](https://ylgrgyq.github.io/2017/07/23/linux-receive-packet-1/ring-buffer.png)

### PF_RING

* mmap
    * mapping kernel_buf and user_buf

###### NIC 到 user space
* cpu copy 1 次

### PF_RING zc

* mmap
    * RX_buffer and user_buf

###### NIC 到 user space
* cpu copy 0 次

![](https://pic1.zhimg.com/v2-fb948361b20f7c63d5f2039d8150d4a8_r.jpg)

### DPDK

* UIO + mmap
    * UIO (userspace driver)
    * mapping RX_buffer and user_buf
* PMD (Poll Mode Driver)
    * 禁用 interrupt 改用 polling
* Huge Pages
    * 減少 TLB miss

###### NIC 到 user space
* cpu copy 0 次

## Reference

[Zero Copy I: User-Mode Perspective](https://www.linuxjournal.com/article/6345)
[一文带你，彻底了解，零拷贝 Zero-Copy 技术](https://xie.infoq.cn/article/340769913d2202f6387550dd8)
[Performance Review of Zero Copy Techniques](https://www.uidaho.edu/~/media/UIdaho-Responsive/Files/engr/research/csds/publications/2012/Performance%20Review%20of%20Zero%20Copy%20Techniques%202012.ashx)
[Linux I/O 原理和 Zero-copy 技术全面揭秘](https://aijishu.com/a/1060000000149804)
[DPDK解析](https://zhuanlan.zhihu.com/p/363622877)
