| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> linux内核零拷贝技术 -> 正文阅读 |
|
[系统运维]linux内核零拷贝技术 |
1. 设计思想 零拷贝技术主要用于磁盘数据通过网络进行交互,常见用法卸载磁盘文件从网络发送出去。常规的卸载文件方法流程如下所示。 从上图可以看出软件流程一共复制了4次数据,内核态到用户态切换4次。 在数据传输的过程中,避免数据在操作系统内核地址空间的缓冲区和用户应用程序地址空间的缓冲区之间进行拷贝。有的时候,应用程序在数据进行传输的过程中不需要对数据进行访问,那么,将数据从 Linux 的页缓存拷贝到用户进程的缓冲区中就可以完全避免,传输的数据在页缓存中就可以得到处理。在某些特殊的情况下,这种零拷贝技术可以获得较好的性能。Linux 中提供类似的系统调用主要有 mmap(),sendfile() 以及 splice()。 mmap(): sendfile(): splice(): 将内核读缓存通过mmap函数映射到应用态,实现内核态和应用态共享该空间。通过mmap函数后会减少一次数据拷贝,上下文切换不变,但是通过异步设计思想可以规避掉上下文切换耗时。 2 代码设计 在内核态分配20个连续的DMA缓存空间,分别标号为1~20,读磁盘和通过网络发送数据实现异步方式,只要有空余的缓存空间,读线程一直读数据到20个缓存空间中,网络发送线程一直发送数据。读数据和发送数据通过循环队列实现,可以使用互斥锁实现循环队列,也可以使用无锁高效互斥队列。 zero_copy_phy_addr是内核态分配的DMA缓存空间的物理地址,注意需要保证cache一致性,该地址在程序初始化时通过ioctl查询到应用态使用,zero_copy_vir_addr是映射该物理地址得到的虚拟地址,在write socket函数中使用。 2.2 读磁盘函数 应用态通过计算需要读写的扇区,然后通过read函数将需要读写的扇区写到内核态,驱动read函数实现如下: 1.拷贝需要读取的扇区信息 2.3 应用态读函数 应用态读线程函数计算需要读取的扇区信息,同时获取是否有空闲的DMA 缓存ID,如果没有就休眠,一直等到有空闲为止。GetCanUseWriteAddr函数就是用来判断是否有可以使用的DMA 缓存 ,网络发送函数中会释放DMA 缓存。 2.4 网络发送函数 SOLO_Read函数用于读取是否有可以使用的数据完成块,注意这个函数是非阻塞的,所以下面有usleep休眠,如果使用了pthread_mutex_lock+ pthread_cond_wait函数互斥的话,那就是阻塞方式获取空闲缓存,我使用的高效无锁互斥,牺牲CPU换取高性能。 3 总结 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/16 0:20:31- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |