首页 > 编程语言 >以C++为低延迟的解决方案总结

以C++为低延迟的解决方案总结

时间:2025-01-06 14:02:37浏览次数:9  
标签:缓存 解决方案 NUMA C++ 线程 内存 共享 CPU 延迟

前言

某天在知乎上看到的问题https://www.zhihu.com/question/23185359/answer/137034841,《以C++为核心语言的高频交易系统是如何做到低延迟的》,感觉问题和答案都非常好,所以想在此归纳和总结一下优秀的答案作为今后的参考

要点总结

为了解决这个问题,可以结合我之前记录的C++行为性能消耗总结消耗占用高的几种行为,我总结出几个要点

1. 减少系统调用

系统调用是用户到内核的切换,频繁调用会消耗较多的时间和资源

2. CPU行为和缓存

行为性能消耗中,NUMA架构下的CPU多核共享缓存消耗也是比较高的,另外利用局部性原理和缓存一致性指定任务配合到同一核、连续的内存分配也是可以优化程序效率的

解决方案

根据要点总结,衍生出以下几种方案

1.限制动态分配内存

问题:C语言中的malloc背后有着非常复杂的算法,其中还会涉及到sbrk()、mmap()等函数,这些函数都涉及到系统调用,因此需要想办法减少内存分配
解决:尽量使用vector或者array(初始化时分配足够的空间,之后每次使用都从里面取出来用)。尽量使用内存池。如果需要二叉树或者哈希表,尽量使用侵入式容器(boost::intrusive)。

侵入式容器和被包含的对象之间有更紧密的耦合关系,一般对象中也会包含容器所需的指向或引用,这样会使操作效率提高

2.使用轮询,尽量避免阻塞

CPU上下文切换是很消耗时间的,包括清理现场和恢复现场(寄存器、流水线等)、内核调度、缓存命中等,可以参考另外一篇我的文章,C++行为性能消耗总结,其中线程切换是非常消耗时间的
解决:减少进程或线程使用,减少锁的使用,IO复用等

3.使用共享内存作为唯一的IPC机制

核心思想还是减少系统调用,因为共享内存只有在初始化是才会有系统调用,不会像其他机制一样(管道、消息队列、套接字),每次数据传递都会进行系统调用,因此共享内存是最快的IPC机制
解决:

  1. 如标题所讲,使用共享内存作为唯一的IPC机制
  2. 使用自己编写或开源的无锁内存池、无锁队列和顺序锁

4.考虑缓存对速度的影响

由于CPU的局部性原理和缓存一致性,所以在容器使用上尽量使用内存连续的容器,不仅可以提高缓存命中率,还能减少伪共享带来的跨核可视延时。其次,指定cpu affinity时考虑LLC缓存
当涉及到指定CPU亲和性(CPU affinity)时,考虑LLC缓存的层次结构以及数据访问模式对于优化性能至关重要。你提到的描述涉及到了多核处理器中的缓存共享关系、NUMA架构下的通信机制以及避免伪共享(false sharing)的策略。让我们逐一解释这些概念。

  1. CPU亲和性和缓存层次
    超线程(Hyper-Threading):在同一个物理核心上启用超线程技术后,该核心可以同时执行两个逻辑线程。这两个逻辑线程共享同一套L1缓存,但各自拥有独立的寄存器集。因此,在设置CPU亲和性时,如果任务之间有大量交互或需要共享资源,将它们分配到同一物理核心的不同逻辑线程上可能会带来性能上的好处。
    多核处理器:在一个物理CPU芯片内部,多个物理核心可以共享最后一级缓存(LLC,通常为L3缓存)。这意味着,如果你的任务被安排在同一物理CPU的不同核心上运行,它们可以更高效地共享和访问缓存数据,减少了跨CPU通信的需求。
    NUMA架构:Non-Uniform Memory Access(非一致内存访问)架构下,每个CPU节点都有自己的本地内存,并且可以通过QPI(QuickPath Interconnect)或其他互连总线访问其他节点的内存。不同NUMA节点之间的通信通常比本地内存访问要慢得多。因此,在设定CPU亲和性时,尽量让相关联的任务位于同一个NUMA节点内,以减少跨节点通信带来的延迟。
  2. 缓存行对齐与伪共享
    缓存行对齐:现代CPU以固定大小的数据块——称为缓存行(cache line),通常是64字节——来管理和传输数据。为了确保效率,程序员应该确保频繁一起使用的变量尽可能地放置在同一缓存行中,而那些很少一起使用或者可能引发竞争条件的变量则应尽量分散开来。
    伪共享(False Sharing):这是指即使两个不同的变量位于不同的CPU核心上操作,但如果它们恰好落在同一个缓存行中,那么修改其中一个变量会导致整个缓存行在各个核心间的来回传输,从而降低性能。为了避免这种情况,你应该确保被多个线程频繁读写的变量按照缓存行边界进行对齐,即每个变量都占据完整的缓存行,或者至少保证不会与其他不相关的变量共享同一个缓存行。
    实际应用建议
    根据上述原则,当你在设计高性能并行应用程序时:
    合理分配线程:利用pthread_setaffinity_np(Linux)或类似API来绑定线程到特定的CPU核心,尽量将高度关联的任务放在同一物理核心或同一NUMA节点上。
    优化数据布局:使用编译器提供的属性(如GCC的__attribute__((aligned(64))))来确保重要数据结构按照缓存行边界对齐,避免伪共享问题。
    监控和调优:通过性能分析工具(如Intel VTune Profiler, Perf等)监控缓存命中率、缓存行迁移次数等指标,以便及时调整程序逻辑和数据结构,进一步优化性能。
    总之,理解并正确利用CPU缓存层次结构对于构建高效的并发程序非常重要。合理的CPU亲和性配置和数据布局可以帮助最大限度地发挥硬件潜能,减少不必要的开销。

总结

以上就是我对C++低延迟的解决方案总结,如有其他方法我也会跟进补充,如果对你有帮助的话拜托点赞收藏,谢谢!

标签:缓存,解决方案,NUMA,C++,线程,内存,共享,CPU,延迟
From: https://blog.csdn.net/m0_47666995/article/details/144886939

相关文章

  • Vue+Elementui: el-select组件下拉数据量大,产生页面卡顿或崩溃,详细解决方案!
    1.安装插件npminstallvue-virtual-scroll-list2.封装组件1>新建文件夹VirtualSelect创建文件:index.vue,OptionNode.vue/VirtualSelect/index.vue<template><div><el-selectsize="mini"popper-class="virtualselect"......
  • MyBatis 一对一查询中的列名冲突问题及多种解决方案
    MyBatis一对一查询中的列名冲突问题及多种解决方案引言在使用MyBatis进行数据库操作时,尤其是在处理多表关联查询时,我们经常会遇到列名冲突的问题。这种问题通常是由于查询结果中出现了重复的列名,导致MyBatis在映射结果时无法正确区分这些列。本文将详细描述我在开发过程中......
  • 中电金信携手华为发布“全链路实时营销解决方案”,重塑金融营销数智新生态
    在数智化转型成为驱动经济社会高质量发展的新引擎背景下,“数智方案”栏目聚焦金融等国计民生重点行业场景,依托中电金信“源启筑基+咨询引领+应用重构”的产品及服务体系,输出市场洞察和行业解决方案、应用案例,旨在全面推动行业IT架构升级、数智化转型。  数智驱动是金融机构营......
  • 欧洲位置传感器 (Sensor) + 以太联Intellinet PoE智能解决方案助力数字转型
    在快速变化的市场中,精准定位与高效网络管理成为各行各业提升竞争力的关键因素。无论是医疗中心还是物流仓储,透过欧洲sensor制造商与以太联—Intellinet网络解决方案的整合,企业能实现资产追踪自动化、提升运营效率,并降低碳排放。以太联-Intellinet的self-HealingNetwork技术与......
  • Mysql8忽略大小写的解决方案.240105
    ​一、删除服务器数据文件由于8.0没法设置参数后重启(失败),所以必须删掉老库,重新启动才行。切记:;本步骤要删掉老库所有资料,如果是数据库当前有用,请做好备份,再进行操作。systemctlstopmysqldcd/var/lib/mysql默认数据在这里rm-rf*二、添加配置,大小写不敏感vim/etc/m......
  • 供应链计划性能优化解决方案-Clickhouse本地Join
    作者:京东零售姜波前言本文主要针对供应链计划业务发展过程中系统产生的瓶颈问题的解决方案进行阐述,并且分享一些问题解决过程中用到的一些工具方法,希望对其他业务同类问题提供启发,原理细节不着重介绍,如有兴趣欢迎一起探讨。业务背景供应链计划业务目前数据库主要使用了Tidb和......
  • 项目管理不再是难题:一揽子解决方案助你轻松前行
    一、项目管理的核心要素●范围管理:明确项目的范围和目标,确保项目的各个方面都在预定的范围内。范围管理包括范围定义、范围确认、范围控制等方面的工作。●时间管理:通过合理的时间安排和控制,确保项目按时完成。时间管理包括进度计划、进度控制、进度评估等方面的工作。●成......
  • 启航数据结构算法之雅舟,悠游C++智慧之旅——线性艺术:顺序表之细腻探索
    人无完人,持之以恒,方能见真我!!!共同进步!!文章目录一、线性表的概念二、顺序表1.概念与结构2.顺序表的分类静态顺序表动态顺序表三、顺序表的实现1.顺序表的结构2.顺序表的初始化和销毁初始化函数销毁函数3.顺序表的扩容4.顺序表的尾插和头插尾插函数头插函数5.顺序......
  • linux下很多软件无法输入中文的完美解决方案:对话框+wl-clipboard
    如blender,ueforlinux,reaper等,由于没有处理编译linux下与输入法相关的.so文件,无法切换中文输入法。需要wayland协议的桌面zenity/yad/kdinput(有拉伸窗口,位置乱跳bug)脚本+快捷键xdotoolkeyctrl+c;zenity--entry--text=$(wl-paste)|wl-copy--paste-once&&w......
  • 【开源】pgrok : 一个针对小团队的多租户 HTTP/TCP 反向代理解决方案
    背景介绍在进行软件开发、远程协作和产品测试阶段时,开发团队或许会面临一个问题,如何将本地的开发环境稳定且安全的提供给公网的其他用户进行访问?这其中涉及到了自己搭建反向代理的问题,以及项目如何对接单点登录服务提供商等一系列问题。今天要给大家推荐一个GitHub开源项目pg......