DPDK-利用DPDK开发项目应该注意的性能点

来源:互联网 发布:樟脑丸 蟑螂 知乎 编辑:程序博客网 时间:2024/06/02 05:12

0x01 缘由

    最近也在尝试写一个DPDK应用程序,也是对之前的学习做一下检验。然而在编写过程中,发现自己陷入到一个码API的思路中,完全没有考虑到DPDK的设计思想,于是放开编程指南,学习下。

0x02 写高效的代码

    Intel® 64 and IA-32 指导手册。
    1.内存
    内存拷贝:建议不要使用libc中的memcpy函数,而用rte_memcpy(),dpdk中做了一些优化。
    内存分配:建议使用固定的内存池,减少动态回收内存碎片带来的性能开销,dpdk中的内存池库:librte_mempool、rte_malloc()。
    并发访问同一块内存区域:避免多个核并发的访问同一块内存区域,减少Cache misses 应该有如下两种方式避免:
    用RTE_PER_LCORE 变量;用一个结构表,每个结构必须Cache对齐;
    NUMA系统:尽量访问本地内存,不访问远端内存。DPDK中很多结构中创建函数中都需要制定对应的socket。以空间换时间的思路。
    跨存储器通道分配:现代内存控制器有多个内存通道。
    2.逻辑核间的通讯(通常是线程):DPDK建议用ring结构。
    3.PMD驱动(DPDK轮询模式驱动)
    避免局部写。
    更低的包延迟:为了获得更高的吞吐量,DPDK尝试用突发的方式合并每个包的处理。
    4.锁和原子操作
    原子操作意味着在指令之前有一个锁定前缀,导致处理器的LOCK#信号在执行下一条指令时被断言。Read-Copy-Update (RCU) 算法代替rwlocks。
    5.代码编写上考量
    内联函数(inline):小的函数可以在头文件静态内联函数。
    分支预测:intel C/C++编译器(icc/gcc)内建了likely() unlikely()函数。
    6.设定CPU类型
    DPDK通过配置文件中的CONFIG_RTE_MACHINE选项支持CPU微体系结构特定的优化。优化程度取决于编译器针对特定微架构进行优化的能力,因此,只要有可能,最好使用最新的编译器版本。除了编译器优化之外,一组预处理器定义会自动添加到构建过程中(不管编译器版本如何)。 这些定义对应于目标CPU应该能够支持的指令集。 例如,为任何支持SSE4.2的处理器编译的二进制文件将定义RTE_MACHINE_CPUFLAG_SSE4_2,从而为不同的平台启用编译时代码路径选择。

0x03 性能检测

VTune Performance Analyzer Essentials

0x04 总结

    DPDK不仅仅学理论得学解决方案和实践操作。