C++ 中频事件队列的设计与构建

C++ 中频事件队列的设计与实现

一、概述

本文所示事件队列设计目标为:解决同一股票代码事件严格有序多核并行处理的问题。
在这里插入图片描述

1.2 频率分级

低频
<100K EPS
中频
2M EPS
高频
5M EPS
超高频
>10M EPS

定义

  • 低频(<100K EPS):传统线程池即可满足,如后台报表系统
  • 中频(2M EPS)本事件队列设计目标,适用多数量化策略
  • 高频(5M EPS):需专项优化,适用高频做市商系统
  • 超高频(>10M EPS):需SPSC专用队列,适用极致延迟交易

二、核心

2.1 结构图

股票代码A
股票代码B
股票代码C
...
关键设计原则
顺序保证
同一股票串行处理
不同股票并行处理
性能最大化
动态负载均衡
智能调度
事件源
多线程投递
事件分发器
Strand 0
股票A专属队列
Strand 1
股票B专属队列
Strand 2
股票C专属队列
Strand N...
ConcurrentQueue
无锁多生产者队列
ConcurrentQueue
无锁多生产者队列
ConcurrentQueue
无锁多生产者队列
调度链表
schedules_
轮询调度器
run_once循环
工作线程池

2.2 Strand:顺序性与并行性

2.2.1 Strand 定位

在量化交易中,同一股票代码的交易指令必须严格有序处理,否则会导致交易逻辑错误。传统解决方案存在的问题:

解决方案:Strand模型
问题:传统多线程模型
无法保证顺序
无法保证顺序
并行执行
并行执行
严格顺序:
委托1→委托2→委托3
Strand A
专用于股票A
严格顺序:
委托1→委托2→委托3
Strand B
专用于股票B
严格顺序:
委托1→委托2→委托3
Strand C
专用于股票C
线程2: 股票A委托2
可能乱序执行
线程1: 股票A委托1
线程3: 股票A委托3
可能乱序执行

Strand 特性

  1. 顺序保证(Sequential Consistency):同一Strand内事件严格FIFO
  2. 并行处理(Parallel Processing):不同Strand可并行执行
  3. 资源隔离(Resource Isolation):每个Strand独立队列,减少竞争
  4. 动态扩展(Dynamic Scaling):Strand数量可根据股票数量动态调整
2.2.2 防止伪共享
class strand final {
// 每个成员64字节对齐,确保独占缓存行
alignas(64) StrandLinkedListNode        node_;      // 64字节
alignas(64) moodycamel::ConcurrentQueue<Handler> handers_; // 64字节
  alignas(64) uint32_t                    id_ = 0;    // 64字节
  alignas(64) std::atomic<int>            size_ = 0;  // 64字节
    alignas(64) std::atomic<int64_t>        executing_ = 0; // 64字节
      alignas(64) context&                    executor_;  // 64字节
      };
CPU缓存行对齐原理
无伪共享竞争
无伪共享竞争
无伪共享竞争
无伪共享竞争
缓存行0: 64字节
CPU核心0
缓存行1: 64字节
CPU核心1
缓存行2: 64字节
CPU核心2
缓存行3: 64字节
CPU核心3
包含Strand 0全部数据
包含Strand 1全部数据
包含Strand 2全部数据
包含Strand 3全部数据
高性能

伪共享(False Sharing)问题

MESI协议状态变化
64字节对齐解决方案
伪共享问题产生机制
Modified: 已修改
缓存行状态
Exclusive: 独占
Shared: 共享
Invalid: 无效
频繁M←→I状态转换
伪共享时
总线流量增加
性能下降
不同变量共享同一缓存行
问题根源
每个变量独占缓存行
解决方案
alignas(64)修饰符
实现方式
内存分配对齐
数据结构设计
完全消除伪共享
性能提升显著
修改缓存行中位置X
CPU核心0
修改同一缓存行中位置Y
CPU核心1
缓存行标记为脏
缓存行标记为脏
触发缓存一致性协议
MESI协议状态变更
缓存行在核心间无效化传输
性能严重下降
  • 现代CPU缓存行通常为64字节
  • 不同核心修改同一缓存行的不同部分会触发缓存一致性协议
  • 导致性能下降30-50%
  • alignas(64)确保每个核心独占缓存行

2.3 调度链表(schedules_)

2.3.1 传统链表

schedules_ 采用C++98/03风格的手动管理链表,而非现代STL容器,主要考虑:

性能对比分析
多线程访问模式
LinkedList类内存布局
未对齐链表
操作类型
64字节对齐链表
150-200ns
头节点插入
50-80ns
120-180ns
尾节点插入
40-70ns
80-120ns
并发计数读取
20-40ns
独占访问缓存行0
线程A: 频繁修改m_first
独占访问缓存行1
线程B: 频繁修改m_last
独占访问缓存行2
线程C: 频繁读取m_count
无缓存一致性协议开销
缓存行0: m_first指针
LinkedList实例
缓存行1: m_last指针
缓存行2: m_count计数
缓存行3-...: 虚表指针/填充
2.3.2 调度算法
生产者线程Strand队列调度链表工作线程自旋锁1. 事件投递阶段post(event) 投递事件handers_.enqueue(event)size_++ 原子增加计数lock() 获取锁获取成功AddLast(node) 添加到链表尾unlock() 释放锁alt[队列从空变为非空]2. 事件处理阶段lock() 获取锁获取成功First() 获取第一个节点Remove(node) 从链表移除AddLast(node) 移到链表尾unlock() 释放锁run_once() 执行事件处理CAS(executing_, 0, tid)批量处理循环开始try_dequeue_bulk(hs, 32)执行hs[i]() 事件处理size_.fetch_sub(n)loop[批量处理32个事件]关键优化点r = size_.fetch_sub(n)events += nlock() 获取锁获取成功Remove(node) 从调度链表移除unlock() 释放锁alt[r == n (队列变空)]executing_ = 0 释放执行权生产者线程Strand队列调度链表工作线程自旋锁

三、性能瓶颈

3.1 std::function 性能分析

3.1.1 std::function 内存开销
与函数指针对比
性能问题分析
std::function内部结构
直接调用: 1-2ns
函数指针
无内存分配
可内联优化
调用开销
问题类型
内存分配
类型擦除
虚函数调用开销: 10-20ns
可能触发堆分配: 100+ns
无法内联优化
小对象优化缓冲区
std::function对象
堆内存指针
invoke函数指针
manager函数指针
最大16字节
存储小型可调用对象
超过16字节的
大型可调用对象
3.1.2 为什么使用 std::function 而非函数指针

尽管 std::function 有性能开销,但选择它有以下理由:

  1. 灵活性:支持任意可调用对象(函数、lambda、成员函数等)
  2. 类型安全:编译时类型检查
  3. 内存管理:自动管理捕获的变量生命周期
  4. 与现代C++生态兼容:与STL算法、异步操作、Lambda 函数等良好集成

对于性能敏感场景:

// 优化方案:使用函数指针+上下文参数
typedef void (*EventHandler)(void* context, EventData* data);
struct Event {
EventHandler handler;
void* context;
EventData* data;
// 使用内存池避免动态分配
static memory_pool<Event> pool;
  void execute() {
  handler(context, data);
  }
  };

3.2 无锁队列 vs 环形缓冲区

性能对比数据
本事件队列选择无锁队列的原因
技术选型对比分析
环形缓冲区
操作类型
无锁队列
100-200ns
单生产者单消费者
150-250ns
需要加锁: 500ns+
多生产者单消费者
无锁: 200-300ns
多生产者支持
事件队列需求
容量不确定
需要弹性
多个事件源向同一股票投递
无法预测最大事件数
根据负载动态调整
固定预分配大小
环形缓冲区
严格FIFO保证
SPSC模式最佳
零动态分配
可能动态分配
无锁队列
FIFO保证
MPSC模式最佳
动态弹性扩展

3.3 批量处理

int context::strand::run_once() noexcept
{
static constexpr size_t BATCH_SIZE = 32;  // 经验优化值
// 批量出队:减少锁竞争和函数调用
size_t n = handers_.try_dequeue_bulk(hs, BATCH_SIZE);
if (n) {
// 批量执行:分摊开销,提升缓存命中率
for (size_t i = 0; i < n; i++) {
hs[i]();  // 执行事件处理
}
// 关键优化:正确判断队列是否变空
size_t r = size_.fetch_sub(n);
events += n;
if (r == n) {  // 如果减之前的值等于n,说明减之后为0
executor_.schedule(&node_, false);
}
}
}
BATCH_SIZE选择依据
批量处理
缓存行大小
影响因素
函数调用开销
事件处理时间
64字节/事件 ≈ 8-16事件
函数调用10-20ns
事件处理50-200ns
理论最佳: 8-16
实践建议: 16-32
最终选择: 32
32次函数调用开销
单事件处理模式
32次内存屏障
低缓存命中率
1次批量调用
批量处理模式
1次原子操作
高缓存命中率
函数调用开销减少97%
性能提升分析
内存屏障减少97%
缓存效率提升300%+

四、性能测试

4.1 测试环境

基于提供的测试数据,硬件配置如下:

测试参数设置
测试硬件环境
4个strand并行
测试规模
每个strand 4000万事件
总计1.6亿事件
使用4个工作线程
线程配置
4个strand执行线程
1个统计收集线程
系统预留线程
Intel i7-12700
CPU配置
12物理核心
20逻辑线程
基础频率2.1GHz
睿频4.9GHz
25.6MB L3缓存
64GB DDR5
内存配置
标称速度4800MT/s
实际运行4400MT/s
Ubuntu 22.04 LTS
系统配置
x86_64架构
Linux内核5.15+

4.2 测试结果

4.2.1 各Strand完成时间分布
018003600540072009000108001260014400Strand 1 Strand 0 Strand 2 Strand 3 各Strand完成时间Strand完成时间分布(单位:毫秒)
4.2.2 EPS性能指标
性能评估结论
事件队列总体吞吐量
各Strand平均EPS性能
2.0M-2.3M EPS
单Strand性能
10.4M EPS
事件队列总吞吐
中频: 2M EPS
设计目标对比
160,000,000
总处理事件数
~15.4秒
总处理时间
~10,389,610
事件队列平均EPS
2,774,309.89 EPS
Strand 0
2,778,935.67 EPS
Strand 1
2,600,611.14 EPS
Strand 2
2,593,361.00 EPS
Strand 3
4.2.3 性能波动

在这里插入图片描述

波动点

  1. 初始阶段(0-1秒):高EPS(3.1M-3.7M),CPU睿频+缓存预热
  2. 稳定阶段(1-13秒):稳定EPS(2.0M-2.3M),事件队列进入稳态
  3. 收尾阶段(13-14秒):EPS分化,部分strand完成早
  4. Strand 2/3最后冲刺:EPS突增到5.2M+,其他strand已完成

波动原因

  • CPU频率调节:Intel Turbo Boost动态调整频率
  • 缓存预热效应:初始阶段L1/L2/L3缓存未命中率高
  • 内存带宽竞争:多核心共享内存控制器带宽
  • 操作系统调度:线程切换、中断处理等开销
  • 负载不均衡:不同strand处理速度有差异

4.3 连续性测试

连续性保证的重要意义
连续性测试验证结果
同一股票事件严格有序
金融交易核心需求
无事件丢失或乱序
事件队列可靠性验证
委托1→委托2→委托3
事件完整性保证
满足交易所要求
0个连续性错误 ✓
Strand 0
0个连续性错误 ✓
Strand 1
0个连续性错误 ✓
Strand 2
0个连续性错误 ✓
Strand 3

五、适用场景

5.1 适用场景

交易策略适用性分析
主要交易所性能匹配度
频率: 低频(秒级)
统计套利策略
完全适用 ✓
频率: 中低频
趋势跟踪策略
完全适用 ✓
频率: 高频
做市商策略
边界适用 ⚠
频率: 超高频
高频做市策略
不适用 ✗
频率: 中频
事件驱动套利
适用 ✓
峰值需求: 80-100万/秒
上海/深圳证券交易所
平均需求: 20-50万/秒
本事件队列能力: 200万+/秒 ✓
峰值需求: 500万+/秒
纳斯达克/纽约交易所
单通道需求: 100-200万/秒
本事件队列能力: 边界满足 ⚠

5.2 性能限制

主要性能限制因素
高影响程度
std::function内存分配
优化建议:函数指针+内存池
中影响程度
链表操作锁竞争
优化建议:无锁链表/环形缓冲区
中影响程度
缓存一致性开销
优化建议:更好数据局部性
低影响程度
线程调度开销
优化建议:核心绑定/实时优先级
中影响程度
内存屏障开销
优化建议:减少不必要原子操作

六、代码

6.1 LinkedList.h in C++ 99 实现

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <assert.h>
  #include <atomic>
    // 前向声明LinkedList模板类
    template<typename T>
      class LinkedList;
      // 链表节点模板结构体
      template<typename T>
        struct LinkedListNode
        {
        public:
        // 所有成员64字节对齐,防止伪共享
        alignas(64) std::atomic<LinkedListNode<T>*> Previous;  // 前驱节点指针,原子操作保证线程安全
          alignas(64) std::atomic<LinkedListNode<T>*> Next;      // 后继节点指针,原子操作保证线程安全
            alignas(64) T Value;                                   // 节点存储的值,模板类型T
            alignas(64) std::atomic<LinkedList<T>*> LinkedList_;   // 所属链表指针,用于快速查找链表
              };
              // 链表模板类
              template<typename T>
                class LinkedList
                {
                private:
                // 链表头节点指针,原子操作保证线程安全
                alignas(64) std::atomic<LinkedListNode<T>*> m_first;
                  // 链表尾节点指针,原子操作保证线程安全  
                  alignas(64) std::atomic<LinkedListNode<T>*> m_last;
                    // 链表节点数量,原子操作保证线程安全
                    alignas(64) std::atomic<int> m_count;
                      public:
                      // 构造函数:初始化空链表
                      LinkedList()
                      {
                      this->m_count = 0;     // 节点计数初始化为0
                      this->m_first = NULL;  // 头节点指针初始化为空
                      this->m_last = NULL;   // 尾节点指针初始化为空
                      }
                      // 获取链表头节点
                      LinkedListNode<T>* First();
                        // 获取链表尾节点
                        LinkedListNode<T>* Last();
                          // 获取链表节点数量
                          int Count();
                          // 在链表头部添加节点
                          bool AddFirst(LinkedListNode<T>* value);
                            // 在链表尾部添加节点
                            bool AddLast(LinkedListNode<T>* value);
                              // 在指定节点后添加新节点
                              bool AddAfter(LinkedListNode<T>* node, LinkedListNode<T>* value);
                                // 在指定节点前添加新节点
                                bool AddBefore(LinkedListNode<T>* node, LinkedListNode<T>* value);
                                  // 移除链表头节点
                                  bool RemoveFirst();
                                  // 移除链表尾节点
                                  bool RemoveLast();
                                  // 移除指定节点
                                  bool Remove(LinkedListNode<T>* node);
                                    // 查找包含指定值的节点
                                    LinkedListNode<T>* Find(T value);
                                      // 清空链表所有节点
                                      void Clear();
                                      };
                                      #endif
                                      // 实现:获取链表头节点
                                      template<typename T>
                                        inline LinkedListNode<T>* LinkedList<T>::First()
                                          {
                                          return this->m_first;  // 直接返回头节点指针
                                          }
                                          // 实现:获取链表尾节点
                                          template<typename T>
                                            inline LinkedListNode<T>* LinkedList<T>::Last()
                                              {
                                              return this->m_last;  // 直接返回尾节点指针
                                              }
                                              // 实现:获取链表节点数量
                                              template<typename T>
                                                inline int LinkedList<T>::Count()
                                                  {
                                                  return this->m_count;  // 直接返回节点计数
                                                  }
                                                  // 实现:在链表头部添加节点
                                                  template<typename T>
                                                    inline bool LinkedList<T>::AddFirst(LinkedListNode<T>* value)
                                                      {
                                                      if (value == NULL)  // 参数检查:节点指针不能为空
                                                      {
                                                      return false;
                                                      }
                                                      // 初始化新节点属性
                                                      value->LinkedList_ = NULL;  // 清空所属链表指针
                                                      value->Next = NULL;         // 清空后继指针
                                                      value->Previous = NULL;     // 清空前驱指针
                                                      if (this->m_last == NULL)  // 如果链表为空(尾节点为空)
                                                      {
                                                      this->m_last = value;   // 尾节点指向新节点
                                                      this->m_first = value;  // 头节点指向新节点
                                                      this->m_count = 0;      // 重置计数(下面会正确增加)
                                                      }
                                                      else  // 如果链表非空
                                                      {
                                                      LinkedListNode<T>* current = this->m_first;  // 获取当前头节点
                                                        value->Next = current;   // 新节点的后继指向原头节点
                                                        current->Previous = value;  // 原头节点的前驱指向新节点
                                                        this->m_first = value;   // 更新头节点为新节点
                                                        }
                                                        this->m_count++;             // 节点计数增加
                                                        value->LinkedList_ = this;   // 设置节点的所属链表为当前链表
                                                        return true;                 // 返回操作成功
                                                        }
                                                        // 实现:在链表尾部添加节点
                                                        template<typename T>
                                                          inline bool LinkedList<T>::AddLast(LinkedListNode<T>* node)
                                                            {
                                                            if (node == NULL)  // 参数检查:节点指针不能为空
                                                            {
                                                            return false;
                                                            }
                                                            // 初始化新节点属性
                                                            node->LinkedList_ = NULL;  // 清空所属链表指针
                                                            node->Next = NULL;         // 清空后继指针
                                                            node->Previous = NULL;     // 清空前驱指针
                                                            if (this->m_last == NULL)  // 如果链表为空
                                                            {
                                                            this->m_first = node;   // 头节点指向新节点
                                                            this->m_last = node;    // 尾节点指向新节点
                                                            this->m_count = 0;      // 重置计数
                                                            this->m_count++;        // 节点计数增加
                                                            node->LinkedList_ = this;  // 设置节点的所属链表
                                                            return true;            // 返回操作成功
                                                            }
                                                            else  // 如果链表非空
                                                            {
                                                            return this->AddAfter(this->m_last, node);  // 在尾节点后添加新节点
                                                            }
                                                            }
                                                            // 实现:在指定节点后添加新节点
                                                            template<typename T>
                                                              inline bool LinkedList<T>::AddAfter(LinkedListNode<T>* node, LinkedListNode<T>* value)
                                                                {
                                                                if (node == NULL || value == NULL)  // 参数检查:两个节点都不能为空
                                                                {
                                                                return false;
                                                                }
                                                                // 初始化新节点属性
                                                                value->LinkedList_ = NULL;  // 清空所属链表指针
                                                                value->Next = NULL;         // 清空后继指针
                                                                value->Previous = NULL;     // 清空前驱指针
                                                                LinkedListNode<T>* current = node->Next;  // 获取原节点的后继节点
                                                                  node->Next = value;  // 原节点的后继指向新节点
                                                                  if (current != NULL)  // 如果原节点有后继节点
                                                                  {
                                                                  current->Previous = value;  // 原后继节点的前驱指向新节点
                                                                  }
                                                                  value->Previous = node;  // 新节点的前驱指向原节点
                                                                  value->Next = current;   // 新节点的后继指向原后继节点
                                                                  if (node == this->m_last)  // 如果原节点是尾节点
                                                                  {
                                                                  this->m_last = value;  // 更新尾节点为新节点
                                                                  }
                                                                  this->m_count++;           // 节点计数增加
                                                                  value->LinkedList_ = this; // 设置节点的所属链表
                                                                  return true;               // 返回操作成功
                                                                  }
                                                                  // 实现:在指定节点前添加新节点
                                                                  template<typename T>
                                                                    inline bool LinkedList<T>::AddBefore(LinkedListNode<T>* node, LinkedListNode<T>* value)
                                                                      {
                                                                      if (node == NULL || value == NULL)  // 参数检查:两个节点都不能为空
                                                                      {
                                                                      return false;
                                                                      }
                                                                      // 初始化新节点属性
                                                                      value->LinkedList_ = NULL;  // 清空所属链表指针
                                                                      value->Next = NULL;         // 清空后继指针
                                                                      value->Previous = NULL;     // 清空前驱指针
                                                                      LinkedListNode<T>* current = node->Previous;  // 获取原节点的前驱节点
                                                                        if (current == NULL)  // 如果原节点没有前驱(即原节点是头节点)
                                                                        {
                                                                        return this->AddFirst(value);  // 在链表头部添加新节点
                                                                        }
                                                                        current->Next = value;   // 原前驱节点的后继指向新节点
                                                                        node->Previous = value;  // 原节点的前驱指向新节点
                                                                        value->Next = node;      // 新节点的后继指向原节点
                                                                        value->Previous = current;  // 新节点的前驱指向原前驱节点
                                                                        if (node == this->m_first)  // 如果原节点是头节点
                                                                        {
                                                                        this->m_first = value;  // 更新头节点为新节点
                                                                        }
                                                                        this->m_count++;           // 节点计数增加
                                                                        value->LinkedList_ = this; // 设置节点的所属链表
                                                                        return true;               // 返回操作成功
                                                                        }
                                                                        // 实现:移除链表头节点
                                                                        template<typename T>
                                                                          inline bool LinkedList<T>::RemoveFirst()
                                                                            {
                                                                            LinkedListNode<T>* first = this->m_first;  // 获取当前头节点
                                                                              if (first == NULL)  // 如果链表为空
                                                                              {
                                                                              return false;  // 返回操作失败
                                                                              }
                                                                              LinkedListNode<T>* current = first->Next;  // 获取头节点的后继节点
                                                                                // 清空原头节点的属性
                                                                                first->Previous = NULL;      // 清空前驱指针
                                                                                first->LinkedList_ = NULL;   // 清空所属链表指针
                                                                                first->Next = NULL;          // 清空后继指针
                                                                                if (current != NULL)  // 如果存在后继节点
                                                                                {
                                                                                current->Previous = NULL;  // 后继节点的前驱清空
                                                                                }
                                                                                this->m_count--;  // 节点计数减少
                                                                                if (this->m_count <= 0)  // 如果节点数小于等于0
                                                                                {
                                                                                this->m_count = 0;    // 重置计数为0
                                                                                this->m_first = NULL; // 头节点置空
                                                                                this->m_last = NULL;  // 尾节点置空
                                                                                current = NULL;       // 当前节点置空
                                                                                }
                                                                                this->m_first = current;  // 更新头节点为原后继节点
                                                                                return true;              // 返回操作成功
                                                                                }
                                                                                // 实现:移除链表尾节点
                                                                                template<typename T>
                                                                                  inline bool LinkedList<T>::RemoveLast()
                                                                                    {
                                                                                    LinkedListNode<T>* last = this->m_last;  // 获取当前尾节点
                                                                                      if (last == NULL)  // 如果链表为空
                                                                                      {
                                                                                      return false;  // 返回操作失败
                                                                                      }
                                                                                      LinkedListNode<T>* current = last->Previous;  // 获取尾节点的前驱节点
                                                                                        // 清空原尾节点的属性
                                                                                        last->Previous = NULL;      // 清空前驱指针
                                                                                        last->LinkedList_ = NULL;   // 清空所属链表指针
                                                                                        last->Next = NULL;          // 清空后继指针
                                                                                        if (current != NULL)  // 如果存在前驱节点
                                                                                        {
                                                                                        current->Next = NULL;  // 前驱节点的后继清空
                                                                                        }
                                                                                        this->m_count--;  // 节点计数减少
                                                                                        if (this->m_count <= 0)  // 如果节点数小于等于0
                                                                                        {
                                                                                        this->m_count = 0;    // 重置计数为0
                                                                                        this->m_first = NULL; // 头节点置空
                                                                                        this->m_last = NULL;  // 尾节点置空
                                                                                        current = NULL;       // 当前节点置空
                                                                                        }
                                                                                        this->m_last = current;  // 更新尾节点为原前驱节点
                                                                                        return true;             // 返回操作成功
                                                                                        }
                                                                                        // 实现:移除指定节点
                                                                                        template<typename T>
                                                                                          inline bool LinkedList<T>::Remove(LinkedListNode<T>* node)
                                                                                            {
                                                                                            if (node == NULL)  // 参数检查:节点指针不能为空
                                                                                            {
                                                                                            return false;
                                                                                            }
                                                                                            if (node == this->m_first)  // 如果是头节点
                                                                                            {
                                                                                            return this->RemoveFirst();  // 调用移除头节点方法
                                                                                            }
                                                                                            if (node == this->m_last)  // 如果是尾节点
                                                                                            {
                                                                                            return this->RemoveLast();  // 调用移除尾节点方法
                                                                                            }
                                                                                            // 获取目标节点的前驱和后继节点
                                                                                            LinkedListNode<T>* previous = node->Previous;
                                                                                              LinkedListNode<T>* next = node->Next;
                                                                                                // 将前驱节点的后继指向后继节点
                                                                                                previous->Next = next;
                                                                                                // 将后继节点的前驱指向前驱节点
                                                                                                next->Previous = previous;
                                                                                                this->m_count--;  // 节点计数减少
                                                                                                if (this->m_count <= 0)  // 如果节点数小于等于0
                                                                                                {
                                                                                                this->m_count = 0;    // 重置计数为0
                                                                                                this->m_first = NULL; // 头节点置空
                                                                                                this->m_last = NULL;  // 尾节点置空
                                                                                                }
                                                                                                // 清空被移除节点的属性
                                                                                                node->Next = NULL;          // 清空后继指针
                                                                                                node->Previous = NULL;      // 清空前驱指针
                                                                                                node->LinkedList_ = NULL;   // 清空所属链表指针
                                                                                                return true;  // 返回操作成功
                                                                                                }
                                                                                                // 实现:查找包含指定值的节点
                                                                                                template<typename T>
                                                                                                  inline LinkedListNode<T>* LinkedList<T>::Find(T value)
                                                                                                    {
                                                                                                    LinkedListNode<T>* i = this->m_first;  // 从头节点开始遍历
                                                                                                      while (i != NULL)  // 遍历链表直到结束
                                                                                                      {
                                                                                                      if (i->Value == value)  // 如果找到匹配的值
                                                                                                      {
                                                                                                      return i;  // 返回该节点指针
                                                                                                      }
                                                                                                      i = i->Next;  // 移动到下一个节点
                                                                                                      }
                                                                                                      return NULL;  // 未找到,返回空指针
                                                                                                      }
                                                                                                      // 实现:清空链表所有节点
                                                                                                      template<typename T>
                                                                                                        inline void LinkedList<T>::Clear()
                                                                                                          {
                                                                                                          LinkedListNode<T>* i = this->m_first;  // 从头节点开始遍历
                                                                                                            while (i != NULL)  // 遍历链表所有节点
                                                                                                            {
                                                                                                            LinkedListNode<T>* j = i->Next;  // 保存下一个节点的指针
                                                                                                              // 清空当前节点的所有属性
                                                                                                              i->LinkedList_ = NULL;  // 清空所属链表指针
                                                                                                              i->Next = NULL;         // 清空后继指针
                                                                                                              i->Previous = NULL;     // 清空前驱指针
                                                                                                              i = j;  // 移动到下一个节点
                                                                                                              }
                                                                                                              // 重置链表属性
                                                                                                              this->m_first = NULL;  // 头节点置空
                                                                                                              this->m_count = 0;     // 节点计数重置为0
                                                                                                              this->m_last = NULL;   // 尾节点置空
                                                                                                              }

6.2 主事件队列实现

#include <chtrader/stdafx.h>
  #include <iostream>
    #include <chrono>
      #include <atomic>
        #include <iomanip>
          #include <vector>
            #include "LinkedList.h"
            #include "3rd/queue/concurrentqueue.h"
            // 自旋锁类:使用CAS(Compare-And-Swap)操作实现无阻塞同步
            class SpinLock final {
            public:
            /// @brief 加锁操作:使用CAS自旋直到成功获取锁
            void lock() noexcept
            {
            for (;;)  // 自旋循环,直到成功获取锁
            {
            int expected = FALSE;  // 期望状态:锁未被占用(FALSE)
            // CAS原子操作:如果lk_的当前值等于expected,则设置为TRUE
            // memory_order_acquire:获取操作,确保后续读写不会重排到前面
            if (lk_.compare_exchange_strong(expected, TRUE, std::memory_order_acquire))
            {
            break;  // 成功获取锁,退出循环
            }
            }
            }
            /// @brief 解锁操作:释放锁资源
            void unlock()
            {
            int expected = TRUE;  // 期望状态:锁已被占用(TRUE)
            // CAS原子操作:如果lk_的当前值等于expected,则设置为FALSE
            // memory_order_release:释放操作,确保前面的读写不会重排到后面
            bool ok = lk_.compare_exchange_strong(expected, FALSE, std::memory_order_release);
            if (!ok)  // 解锁失败,说明锁状态异常
            {
            throw std::runtime_error("failed to acquire the atomic lock.");
            }
            }
            private:
            alignas(64) std::atomic<int> lk_ = FALSE;  // 原子锁变量,64字节对齐防止伪共享
              };
              // 上下文类:管理所有strand和调度
              class context final {
              typedef SpinLock SynchronizedObject;  // 同步对象类型别名(自旋锁)
              typedef std::lock_guard<SynchronizedObject> SynchronizedObjectScope;  // RAII锁保护作用域
                typedef LinkedListNode<void*> StrandLinkedListNode;  // 链表节点类型,存储void*指针
                  typedef LinkedList<void*> StrandLinkedList;  // 链表类型,存储void*指针
                    public:
                    typedef std::function<void()> Handler;  // 事件处理函数类型,使用std::function包装
                      // Strand类:代表一个处理流水线,每个strand对应一个股票代码
                      class strand final {
                      friend class context;  // 声明context为友元类,允许访问私有成员
                      public:
                      // 构造函数:初始化strand
                      strand(context& executor, uint32_t id) noexcept
                      : id_(id)           // 初始化strand ID
                      , size_(0)          // 初始化事件数量为0
                      , executing_(0)     // 初始化执行状态为未执行
                      , executor_(executor)  // 初始化执行器引用
                      {
                      // 初始化链表节点
                      memset(&node_, 0, sizeof(node_));  // 清零节点内存
                      node_.Value = this;  // 节点值指向当前strand对象
                      executor.add(id_, this);  // 向执行器注册当前strand
                      }
                      // 析构函数:清理资源
                      ~strand() noexcept
                      {
                      executor_.remove(id_, this);  // 从执行器中注销当前strand
                      }
                      public:
                      // 获取执行器引用
                      context& get_executor() noexcept { return executor_; }
                      // 提交事件到当前strand
                      bool post(Handler&& event) noexcept;
                      private:
                      // 执行一次事件处理
                      int run_once() noexcept;
                      // 成员变量,全部64字节对齐防止伪共享
                      alignas(64) StrandLinkedListNode node_;  // 调度链表节点
                      alignas(64) moodycamel::ConcurrentQueue<Handler> handers_;  // 无锁事件队列
                        alignas(64) uint32_t id_ = 0;  // strand标识符
                        alignas(64) std::atomic<int> size_ = 0;  // 队列中事件数量(原子操作)
                          alignas(64) std::atomic<int64_t> executing_ = 0;  // 当前执行线程ID(原子操作)
                            alignas(64) context& executor_;  // 执行器引用
                            };
                            // 公共接口:向指定strand提交事件
                            bool post(uint32_t id, Handler&& event) noexcept;
                            // 执行一次调度处理
                            int run_once() noexcept;
                            // 停止执行器
                            void stop() noexcept;
                            // 运行执行器(主循环)
                            void run() noexcept;
                            private:
                            // 私有方法:添加strand到管理表
                            void add(uint32_t id, strand* strand) noexcept;
                            // 私有方法:从管理表移除strand
                            void remove(uint32_t id, strand* strand) noexcept;
                            // 私有方法:调度strand(添加到调度链表或从链表中移除)
                            void schedule(StrandLinkedListNode* node, bool apply_or_cancel) noexcept;
                            private:
                            // 类型定义
                            typedef chtrader::unordered_map<uint32_t, strand*> StrandTable;
                              // 成员变量,全部64字节对齐防止伪共享
                              alignas(64) SynchronizedObject lockobj_;  // 保护共享数据的自旋锁
                              alignas(64) bool stopped_ = false;  // 停止标志
                              alignas(64) StrandTable strands_;  // strand管理表(ID到strand指针的映射)
                              alignas(64) StrandLinkedList schedules_;  // 调度链表(管理待处理的strand)
                              };
                              // 实现:向指定strand提交事件
                              inline bool context::post(uint32_t id, Handler&& event) noexcept
                              {
                              strand* q = NULL;  // 目标strand指针
                              // 在锁保护下查找目标strand
                              {
                              SynchronizedObjectScope scope(lockobj_);  // RAII锁保护,自动加锁解锁
                              auto tail = strands_.find(id);  // 在strand管理表中查找指定ID
                              auto endl = strands_.end();     // 获取结束迭代器
                              if (tail != endl)  // 如果找到目标strand
                              {
                              q = tail->second;  // 获取strand指针
                              }
                              else  // 未找到目标strand
                              {
                              return false;  // 返回失败
                              }
                              }
                              // 提交事件到目标strand
                              return q->post(std::move(event));  // 使用move语义转移事件所有权
                              }
                              // 实现:执行一次调度处理
                              inline int context::run_once() noexcept
                              {
                              strand* q = NULL;  // 待处理的strand指针
                              // 在锁保护下从调度链表中获取一个待处理的strand
                              {
                              SynchronizedObjectScope scope(lockobj_);  // RAII锁保护
                              if (stopped_)  // 如果执行器已停止
                              {
                              return 0;  // 直接返回
                              }
                              auto node = schedules_.First();  // 获取调度链表第一个节点
                              if (node)  // 如果链表非空
                              {
                              q = static_cast<strand*>(node->Value);  // 获取节点对应的strand指针
                                schedules_.Remove(node);      // 从链表中移除该节点
                                schedules_.AddLast(node);     // 添加到链表尾部(实现轮转调度)
                                }
                                else  // 如果链表为空
                                {
                                return 0;  // 无事可做,返回0
                                }
                                }
                                // 执行strand的事件处理,返回处理的事件数
                                return q ? q->run_once() : 0;
                                }
                                // 实现:运行执行器主循环
                                inline void context::run() noexcept
                                {
                                // 循环执行,直到停止标志被设置
                                while (!stopped_)
                                {
                                run_once();  // 执行一次调度处理
                                }
                                }
                                // 实现:添加strand到管理表
                                inline void context::add(uint32_t id, strand* strand) noexcept
                                {
                                SynchronizedObjectScope scope(lockobj_);  // RAII锁保护
                                strands_[id] = strand;  // 添加到管理表
                                }
                                // 实现:从管理表移除strand
                                inline void context::remove(uint32_t id, strand* strand) noexcept
                                {
                                SynchronizedObjectScope scope(lockobj_);  // RAII锁保护
                                auto tail = strands_.find(id);  // 查找指定ID的strand
                                auto endl = strands_.end();     // 获取结束迭代器
                                // 如果找到且指针匹配,则从管理表中移除
                                if (tail != endl && tail->second == strand)
                                {
                                strands_.erase(tail);
                                }
                                }
                                // 实现:停止执行器
                                inline void context::stop() noexcept
                                {
                                stopped_ = true;  // 设置停止标志
                                }
                                // 实现:调度strand(添加到调度链表或移除)
                                inline void context::schedule(StrandLinkedListNode* node, bool apply_or_cancel) noexcept
                                {
                                SynchronizedObjectScope scope(lockobj_);  // RAII锁保护链表操作
                                if (apply_or_cancel)  // 如果为true,添加到调度链表
                                {
                                if (!node->LinkedList_)
                                {
                                schedules_.AddLast(node);  // 添加到链表尾部
                                }
                                }
                                else  // 如果为false,从调度链表移除
                                {
                                if (node->LinkedList_)
                                {
                                schedules_.Remove(node);   // 从链表中移除
                                }
                                }
                                }
                                // 实现:strand提交事件
                                inline bool context::strand::post(Handler&& event) noexcept
                                {
                                // 将事件添加到无锁队列
                                handers_.enqueue(event);
                                // 如果之前队列为空(size_从0变为1),需要调度
                                // fetch_add返回增加之前的值,所以==0表示从空变为非空
                                if (size_.fetch_add(1) == 0)
                                {
                                executor_.schedule(&node_, true);  // 添加到调度链表
                                }
                                return true;  // 总是返回成功
                                }
                                // 实现:strand执行一次事件处理
                                inline int context::strand::run_once() noexcept
                                {
                                // 尝试获取执行权:将executing_从0设置为当前线程ID
                                int64_t location = 0;  // 期望值:未执行状态(0)
                                // CAS操作:如果executing_当前值为0,则设置为当前线程ID
                                if (!executing_.compare_exchange_strong(location, chtrader::GetCurrentThreadId()))
                                {
                                return 0;  // 其他线程正在执行,直接返回0
                                }
                                // 批量处理大小,经验优化值(基于事件处理时间320-350ns):
                                // 低延迟模式   = 16 * 4      // 最坏延迟约22.4μs,适合超低延迟场景
                                // 平衡模式     = 16 * 8      // 最坏延迟约44.8μs,当前使用配置
                                // 高循环模式   = 16 * 16     // 最坏延迟约89.6μs,适合事件堆积场景
                                // 大批量模式   = 32 * 4      // 最坏延迟约44.8μs,适合计算密集型
                                // 高吞吐模式   = 32 * 8      // 最坏延迟约89.6μs,适合高吞吐场景
                                static constexpr size_t BATCH_SIZE = 16;
                                int events = 0;  // 本次处理的事件计数
                                Handler hs[BATCH_SIZE];  // 事件缓冲区,栈上分配避免堆分配
                                // 批量处理循环
                                for (size_t c = 0; c < 8; c++)
                                {
                                // 尝试批量出队,最多BATCH_SIZE个事件
                                size_t n = handers_.try_dequeue_bulk(hs, BATCH_SIZE);
                                if (n)  // 如果成功出队事件(n>0)
                                {
                                // 批量执行事件处理函数
                                for (size_t i = 0; i < n; i++)
                                {
                                Handler& h = hs[i];
                                h();  // 执行事件处理函数
                                }
                                // 正确更新事件计数并判断队列是否变空
                                size_t r = size_.fetch_sub(n);  // 原子减少事件计数,返回减少之前的值
                                events += n;  // 累加本次处理的事件数
                                // 如果减少之前的值等于n,说明减少之后队列变空
                                if (r == n)
                                {
                                executor_.schedule(&node_, false);  // 从调度链表移除
                                }
                                }
                                else  // 队列为空,退出循环
                                {
                                break;
                                }
                                }
                                // 释放执行权:将executing_设置为0
                                executing_.exchange(0);
                                return events;  // 返回本次处理的事件数
                                }
                                // 统计数据结构,用于性能监控和连续性检查
                                struct StrandStats {
                                uint32_t strand_id = 0;  // strand标识符
                                // 原子计数器,无需锁保护
                                std::atomic<int64_t> total_processed{ 0 };          // 总处理事件数
                                  std::atomic<int64_t> continuity_errors{ 0 };        // 连续性错误数
                                    std::atomic<int64_t> last_sequence{ -1 };           // 上一个序列号(-1表示无)
                                      std::atomic<int64_t> events_this_second{ 0 };       // 当前秒处理的事件数
                                        // 时间戳,用于性能统计
                                        std::chrono::steady_clock::time_point last_report_time = std::chrono::steady_clock::now();
                                        // 性能统计结构
                                        struct Performance {
                                        int64_t min_eps = 0;    // 最小每秒事件数
                                        int64_t max_eps = 0;    // 最大每秒事件数
                                        int64_t avg_eps = 0;    // 平均每秒事件数
                                        int64_t total_seconds = 0; // 统计的总秒数
                                        } performance;
                                        };
                                        // 全局统计收集器类
                                        class StatisticsCollector {
                                        private:
                                        std::vector<std::unique_ptr<StrandStats>> stats_;  // 统计数据集合,使用unique_ptr管理
                                          std::atomic<bool> stop_collector_{ false };        // 停止收集标志(原子操作)
                                            std::thread collector_thread_;                      // 收集线程
                                            std::mutex output_mutex_;                           // 输出保护锁,避免多线程输出混乱
                                            public:
                                            // 构造函数:初始化统计器
                                            StatisticsCollector(size_t num_strands) {
                                            // 为每个strand创建统计对象
                                            for (size_t i = 0; i < num_strands; ++i) {
                                            auto stat = std::make_unique<StrandStats>();  // 创建统计对象
                                              stat->strand_id = static_cast<uint32_t>(i);   // 设置strand ID
                                                stat->last_report_time = std::chrono::steady_clock::now();  // 设置初始时间
                                                stats_.push_back(std::move(stat));  // 添加到集合,转移所有权
                                                }
                                                // 启动统计收集线程
                                                collector_thread_ = std::thread([this]() {
                                                collect_statistics();  // 收集统计信息
                                                });
                                                }
                                                // 析构函数:清理资源
                                                ~StatisticsCollector() {
                                                stop_collector_ = true;  // 设置停止标志
                                                if (collector_thread_.joinable()) {
                                                collector_thread_.join();  // 等待收集线程结束
                                                }
                                                print_final_statistics();  // 打印最终统计结果
                                                }
                                                // 更新统计信息
                                                void update(uint32_t strand_id, int64_t sequence) {
                                                if (strand_id >= stats_.size()) return;  // 参数检查:确保strand_id有效
                                                auto& stat = *stats_[strand_id];  // 获取统计对象引用
                                                // 检查事件连续性
                                                int64_t last_seq = stat.last_sequence.load(std::memory_order_relaxed);
                                                if (last_seq != -1 && last_seq + 1 != sequence) {
                                                // 序列号不连续,记录错误
                                                stat.continuity_errors.fetch_add(1, std::memory_order_relaxed);
                                                }
                                                stat.last_sequence.store(sequence, std::memory_order_relaxed);  // 更新最后序列号
                                                // 更新处理计数
                                                stat.total_processed.fetch_add(1, std::memory_order_relaxed);
                                                stat.events_this_second.fetch_add(1, std::memory_order_relaxed);
                                                }
                                                private:
                                                // 收集统计信息(每秒执行一次)
                                                void collect_statistics() {
                                                using namespace std::chrono;
                                                // 收集循环,直到收到停止信号
                                                while (!stop_collector_) {
                                                std::this_thread::sleep_for(seconds(1));  // 每秒收集一次
                                                auto now = steady_clock::now();  // 当前时间
                                                std::lock_guard<std::mutex> lock(output_mutex_);  // 加锁保护输出
                                                  // 输出统计头
                                                  std::cout << "\n=== 每秒性能统计 ===" << std::endl;
                                                  // 遍历所有strand的统计
                                                  for (auto& stat_ptr : stats_) {
                                                  if (!stat_ptr) continue;  // 跳过空指针
                                                  auto& stat = *stat_ptr;  // 统计对象引用
                                                  auto& perf = stat.performance;  // 性能统计引用
                                                  // 获取本秒事件数并重置计数器
                                                  int64_t events_this_second = stat.events_this_second.exchange(0);
                                                  int64_t total_seconds = ++perf.total_seconds;  // 增加统计秒数
                                                  // 计算每秒事件数
                                                  double eps = static_cast<double>(events_this_second);
                                                    // 更新性能统计
                                                    if (perf.total_seconds == 1) {  // 第一次统计
                                                    perf.min_eps = perf.max_eps = static_cast<int64_t>(eps);
                                                      perf.avg_eps = static_cast<int64_t>(eps);
                                                        } else {  // 后续统计
                                                        perf.min_eps = std::min(perf.min_eps, static_cast<int64_t>(eps));
                                                          perf.max_eps = std::max(perf.max_eps, static_cast<int64_t>(eps));
                                                            // 计算移动平均值
                                                            perf.avg_eps = ((perf.avg_eps * (total_seconds - 1)) + static_cast<int64_t>(eps)) / total_seconds;
                                                              }
                                                              // 输出当前秒的统计信息
                                                              std::cout << "Strand " << stat.strand_id << ": "
                                                              << "本秒处理: " << events_this_second << " 事件, "
                                                              << "EPS: " << std::fixed << std::setprecision(2) << eps
                                                              << ", 累计: " << stat.total_processed.load()
                                                              << ", 连续性错误: " << stat.continuity_errors.load()
                                                              << std::endl;
                                                              }
                                                              }
                                                              }
                                                              // 打印最终统计结果
                                                              void print_final_statistics() {
                                                              std::lock_guard<std::mutex> lock(output_mutex_);  // 加锁保护输出
                                                                std::cout << "\n=== 最终统计结果 ===" << std::endl;
                                                                int64_t total_events = 0;  // 总事件数
                                                                int64_t total_errors = 0;  // 总错误数
                                                                // 遍历所有strand的统计
                                                                for (auto& stat_ptr : stats_) {
                                                                if (!stat_ptr) continue;  // 跳过空指针
                                                                auto& stat = *stat_ptr;  // 统计对象引用
                                                                const auto& perf = stat.performance;  // 性能统计常量引用
                                                                // 累加统计
                                                                total_events += stat.total_processed.load();
                                                                total_errors += stat.continuity_errors.load();
                                                                // 输出单个strand的统计
                                                                std::cout << "\nStrand " << stat.strand_id << " 统计:" << std::endl;
                                                                std::cout << "  总处理事件数: " << stat.total_processed.load() << std::endl;
                                                                std::cout << "  连续性错误数: " << stat.continuity_errors.load() << std::endl;
                                                                std::cout << "  性能统计:" << std::endl;
                                                                std::cout << "    最小EPS: " << perf.min_eps << std::endl;
                                                                std::cout << "    最大EPS: " << perf.max_eps << std::endl;
                                                                std::cout << "    平均EPS: " << perf.avg_eps << std::endl;
                                                                // 根据连续性错误数输出结果
                                                                if (stat.continuity_errors.load() > 0) {
                                                                std::cout << "  ⚠️  检测到连续性错误!" << std::endl;
                                                                }
                                                                else {
                                                                std::cout << "  ✅ 连续性测试通过!" << std::endl;
                                                                }
                                                                }
                                                                // 输出全局统计
                                                                std::cout << "\n=== 全局统计 ===" << std::endl;
                                                                std::cout << "总处理事件数: " << total_events << std::endl;
                                                                std::cout << "总连续性错误: " << total_errors << std::endl;
                                                                // 计算平均每秒事件数
                                                                if (!stats_.empty() && stats_[0]->performance.total_seconds > 0) {
                                                                std::cout << "平均每秒事件数: " << (total_events / stats_[0]->performance.total_seconds) << std::endl;
                                                                  }
                                                                  }
                                                                  };
                                                                  // 主测试函数
                                                                  int main(int argc, const char* argv[])
                                                                  {
                                                                  // 测试参数配置
                                                                  static constexpr int NUM_STRANDS = 4;                       // strand数量
                                                                  static constexpr int EVENTS_PER_STRAND = 40000000;          // 每个strand处理的事件数
                                                                  static constexpr int64_t EVENTS_MAX_NUM = NUM_STRANDS * EVENTS_PER_STRAND;  // 总事件数
                                                                  context ctx;                          // 创建上下文实例
                                                                  StatisticsCollector stats_collector(NUM_STRANDS);  // 创建统计收集器
                                                                  // 使用原子标志控制测试运行
                                                                  std::atomic<bool>* test_running = new std::atomic<bool>{ true };
                                                                    std::atomic<int64_t>* strands_completed = new std::atomic<int64_t>{ 0 };
                                                                      // 为每个strand创建并启动线程
                                                                      for (int i = 0; i < NUM_STRANDS; i++)
                                                                      {
                                                                      std::thread(
                                                                      [&ctx, i, &stats_collector, &test_running, strands_completed]() noexcept
                                                                      {
                                                                      context::strand s(ctx, i);  // 创建strand
                                                                      // 为每个strand创建独立的序列号
                                                                      std::atomic<int64_t> seq{ 0 };
                                                                        // 记录开始时间
                                                                        auto start_time = std::chrono::steady_clock::now();
                                                                        // 提交事件
                                                                        for (int n = 0; n < EVENTS_PER_STRAND; n++)
                                                                        {
                                                                        // 捕获start_time到lambda中
                                                                        auto start_time_copy = start_time;
                                                                        s.post(
                                                                        [i, n, &stats_collector, &seq, start_time_copy, test_running, strands_completed]() noexcept
                                                                        {
                                                                        // 更新统计
                                                                        stats_collector.update(i, n);
                                                                        // 检查连续性
                                                                        int64_t expected = seq.fetch_add(1);
                                                                        if (expected != n) {
                                                                        // 连续性错误已经在StatisticsCollector中统计
                                                                        }
                                                                        // 输出进度(每10万事件输出一次)
                                                                        if (n % 100000 == 0 && n > 0) {
                                                                        auto current_time = std::chrono::steady_clock::now();
                                                                        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
                                                                          current_time - start_time_copy).count();
                                                                          double eps = (n * 1000.0) / duration;
                                                                          std::cout << "Strand " << i << ": 已处理 " << n
                                                                          << " 个事件, 当前EPS: " << std::fixed << std::setprecision(2) << eps << std::endl;
                                                                          }
                                                                          // 如果是最后一个事件
                                                                          if (n == EVENTS_PER_STRAND - 1) {
                                                                          auto end_time = std::chrono::steady_clock::now();
                                                                          auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
                                                                            end_time - start_time_copy).count();
                                                                            std::cout << "\nStrand " << i << " 完成!" << std::endl;
                                                                            std::cout << "  总时间: " << duration << "ms" << std::endl;
                                                                            std::cout << "  平均每秒: " << (EVENTS_PER_STRAND * 1000.0 / duration) << " 事件" << std::endl;
                                                                            }
                                                                            // 增加完成计数器
                                                                            int64_t completed = ++(*strands_completed);
                                                                            if (completed == EVENTS_MAX_NUM) {
                                                                            // 所有strand都完成,可以停止测试
                                                                            *test_running = false;
                                                                            }
                                                                            });
                                                                            }
                                                                            // 运行context
                                                                            ctx.run();
                                                                            }).detach();  // 分离线程,不等待线程结束
                                                                            }
                                                                            // 主线程输出信息
                                                                            std::cout << "测试开始,处理 " << EVENTS_PER_STRAND << " 事件每个strand..." << std::endl;
                                                                            std::cout << "按Enter键提前结束测试,或等待测试完成..." << std::endl;
                                                                            // 简单的控制台输入检测线程
                                                                            std::thread input_thread([test_running]() {
                                                                            std::cin.get();           // 等待用户输入
                                                                            *test_running = false;    // 设置停止标志
                                                                            });
                                                                            input_thread.detach();        // 分离输入线程
                                                                            // 主循环等待测试完成
                                                                            while (*test_running) {
                                                                            std::this_thread::sleep_for(std::chrono::seconds(1));
                                                                            }
                                                                            // 停止context
                                                                            ctx.stop();
                                                                            // 等待一会让统计器完成最后输出
                                                                            std::this_thread::sleep_for(std::chrono::seconds(2));
                                                                            std::cout << "\n测试完成!" << std::endl;
                                                                            // 清理动态分配的内存
                                                                            delete test_running;
                                                                            delete strands_completed;
                                                                            return 0;
                                                                            }

七、总结与评估

7.1 队列特点

  1. 顺序性与并行性

    • 同一股票代码事件严格顺序处理
    • 不同股票代码事件完全并行处理
    • 满足金融交易的核心顺序性要求
  2. 偏向于高性能

    • 64字节缓存行对齐,彻底消除伪共享
    • 批量处理优化(32事件/批),大幅减少开销
    • 无锁队列+自旋锁的混合锁策略

7.2 性能评估

基于测试数据(i7-12700 2100MHz, 64GB DDR4/4400 MT/s)的性能表现:

性能指标测试结果性能评级评估说明
单Strand峰值EPS3.7M+优秀超过预期设计目标
单Strand平均EPS2.0M-2.3M良好稳定在设计目标区间
队列总吞吐量10.4M EPS优秀满足多数交易所需求
连续性错误0完美完全满足金融交易要求
延迟水平≈ 350ns良好适合中频交易

详细测试数据及配置信息

=== 每秒性能统计 ===
Strand 0: 本秒处理: 3756469 事件, EPS: 3756469.00, 累计: 31084864, 连续性错误: 0
Strand 1: 本秒处理: 3765946 事件, EPS: 3765946.00, 累计: 31154114, 连续性错误: 0
Strand 2: 本秒处理: 3164927 事件, EPS: 3164927.00, 累计: 26184956, 连续性错误: 0
Strand 3: 本秒处理: 3123222 事件, EPS: 3123222.00, 累计: 25662011, 连续性错误: 0
Strand 2: 已处理 26200000 个事件, 当前EPS: 2182423.99
Strand 0: 已处理 31100000 个事件, 当前EPS: 2590587.26
Strand 1: 已处理 31200000 个事件, 当前EPS: 2597402.60
Strand 3: 已处理 25700000 个事件, 当前EPS: 2139527.14
Strand 0: 已处理 31200000 个事件, 当前EPS: 2593085.11
Strand 2: 已处理 26300000 个事件, 当前EPS: 2185111.33
Strand 1: 已处理 31300000 个事件, 当前EPS: 2600099.68
Strand 3: 已处理 25800000 个事件, 当前EPS: 2141789.81
Strand 0: 已处理 31300000 个事件, 当前EPS: 2596002.32
Strand 1: 已处理 31400000 个事件, 当前EPS: 2603000.91
Strand 2: 已处理 26400000 个事件, 当前EPS: 2187241.09
Strand 3: 已处理 25900000 个事件, 当前EPS: 2144394.77
Strand 0: 已处理 31400000 个事件, 当前EPS: 2598692.38
Strand 1: 已处理 31500000 个事件, 当前EPS: 2605459.06
Strand 2: 已处理 26500000 个事件, 当前EPS: 2189901.66
Strand 0: 已处理 31500000 个事件, 当前EPS: 2601156.07
Strand 3: 已处理 26000000 个事件, 当前EPS: 2146985.96
Strand 1: 已处理 31600000 个事件, 当前EPS: 2608121.49
Strand 2: 已处理 26600000 个事件, 当前EPS: 2192367.92
Strand 0: 已处理 31600000 个事件, 当前EPS: 2603823.34
Strand 3: 已处理 26100000 个事件, 当前EPS: 2149563.50
Strand 1: 已处理 31700000 个事件, 当前EPS: 2610557.52
Strand 0: 已处理 31700000 个事件, 当前EPS: 2606264.90
Strand 2: 已处理 26700000 个事件, 当前EPS: 2194821.21
Strand 1: 已处理 31800000 个事件, 当前EPS: 2613197.47
Strand 3: 已处理 26200000 个事件, 当前EPS: 2152127.48
Strand 0: 已处理 31800000 个事件, 当前EPS: 2608909.67
Strand 2: 已处理 26800000 个事件, 当前EPS: 2197441.78
Strand 1: 已处理 31900000 个事件, 当前EPS: 2615397.23
Strand 3: 已处理 26300000 个事件, 当前EPS: 2154678.03
Strand 0: 已处理 31900000 个事件, 当前EPS: 2611543.18
Strand 1: 已处理 32000000 个事件, 当前EPS: 2617372.81
Strand 2: 已处理 26900000 个事件, 当前EPS: 2200049.07
Strand 3: 已处理 26400000 个事件, 当前EPS: 2157391.52
Strand 0: 已处理 32000000 个事件, 当前EPS: 2614165.51
Strand 1: 已处理 32100000 个事件, 当前EPS: 2619980.41
Strand 2: 已处理 27000000 个事件, 当前EPS: 2202463.50
Strand 0: 已处理 32100000 个事件, 当前EPS: 2616776.72
Strand 3: 已处理 26500000 个事件, 当前EPS: 2159915.23
Strand 1: 已处理 32200000 个事件, 当前EPS: 2622363.38
Strand 2: 已处理 27100000 个事件, 当前EPS: 2205044.75
Strand 0: 已处理 32200000 个事件, 当前EPS: 2619163.82
Strand 3: 已处理 26600000 个事件, 当前EPS: 2162425.82
Strand 1: 已处理 32300000 个事件, 当前EPS: 2624949.21
Strand 0: 已处理 32300000 个事件, 当前EPS: 2621753.25
Strand 2: 已处理 27200000 个事件, 当前EPS: 2207613.02
Strand 1: 已处理 32400000 个事件, 当前EPS: 2627950.36
Strand 3: 已处理 26700000 个事件, 当前EPS: 2164923.38
Strand 0: 已处理 32400000 个事件, 当前EPS: 2623694.23
Strand 2: 已处理 27300000 个事件, 当前EPS: 2209810.59
Strand 1: 已处理 32500000 个事件, 当前EPS: 2630301.07
Strand 3: 已处理 26800000 个事件, 当前EPS: 2167408.01
Strand 0: 已处理 32500000 个事件, 当前EPS: 2626050.42
Strand 1: 已处理 32600000 个事件, 当前EPS: 2632854.14
Strand 2: 已处理 27400000 个事件, 当前EPS: 2212175.04
Strand 3: 已处理 26900000 个事件, 当前EPS: 2169879.81
Strand 0: 已处理 32600000 个事件, 当前EPS: 2628608.29
Strand 1: 已处理 32700000 个事件, 当前EPS: 2635184.14
Strand 2: 已处理 27500000 个事件, 当前EPS: 2214527.30
Strand 0: 已处理 32700000 个事件, 当前EPS: 2630943.76
Strand 3: 已处理 27000000 个事件, 当前EPS: 2172338.88
Strand 1: 已处理 32800000 个事件, 当前EPS: 2637716.12
Strand 2: 已处理 27600000 个事件, 当前EPS: 2217045.55
Strand 0: 已处理 32800000 个事件, 当前EPS: 2633480.53
Strand 1: 已处理 32900000 个事件, 当前EPS: 2640025.68
Strand 3: 已处理 27100000 个事件, 当前EPS: 2174785.33
Strand 2: 已处理 27700000 个事件, 当前EPS: 2219373.45
Strand 0: 已处理 32900000 个事件, 当前EPS: 2635795.55
Strand 1: 已处理 33000000 个事件, 当前EPS: 2642536.84
Strand 3: 已处理 27200000 个事件, 当前EPS: 2177044.98
Strand 0: 已处理 33000000 个事件, 当前EPS: 2638311.48
Strand 2: 已处理 27800000 个事件, 当前EPS: 2221689.44
Strand 1: 已处理 33100000 个事件, 当前EPS: 2644826.21
Strand 3: 已处理 27300000 个事件, 当前EPS: 2179466.71
Strand 0: 已处理 33100000 个事件, 当前EPS: 2640606.30
Strand 1: 已处理 33200000 个事件, 当前EPS: 2647105.72
Strand 2: 已处理 27900000 个事件, 当前EPS: 2224170.92
Strand 3: 已处理 27400000 个事件, 当前EPS: 2181876.09
Strand 0: 已处理 33200000 个事件, 当前EPS: 2643101.66
Strand 1: 已处理 33300000 个事件, 当前EPS: 2649375.45
Strand 2: 已处理 28000000 个事件, 当前EPS: 2226463.10
Strand 0: 已处理 33300000 个事件, 当前EPS: 2645376.55
Strand 3: 已处理 27500000 个事件, 当前EPS: 2184273.23
Strand 1: 已处理 33400000 个事件, 当前EPS: 2651845.97
Strand 2: 已处理 28100000 个事件, 当前EPS: 2228743.65
Strand 0: 已处理 33400000 个事件, 当前EPS: 2647641.70
Strand 1: 已处理 33500000 个事件, 当前EPS: 2654096.02
Strand 3: 已处理 27600000 个事件, 当前EPS: 2186658.22
Strand 2: 已处理 28200000 个事件, 当前EPS: 2231365.72
Strand 0: 已处理 33500000 个事件, 当前EPS: 2650106.80
Strand 1: 已处理 33600000 个事件, 当前EPS: 2655916.53
Strand 3: 已处理 27700000 个事件, 当前EPS: 2188858.16
Strand 0: 已处理 33600000 个事件, 当前EPS: 2652980.66
Strand 2: 已处理 28300000 个事件, 当前EPS: 2233799.04
Strand 1: 已处理 33700000 个事件, 当前EPS: 2658147.97
Strand 3: 已处理 27800000 个事件, 当前EPS: 2191046.66
Strand 0: 已处理 33700000 个事件, 当前EPS: 2655215.88
Strand 2: 已处理 28400000 个事件, 当前EPS: 2236220.47
Strand 1: 已处理 33800000 个事件, 当前EPS: 2660369.93
Strand 0: 已处理 33800000 个事件, 当前EPS: 2657441.62
Strand 3: 已处理 27900000 个事件, 当前EPS: 2193396.23
Strand 1: 已处理 33900000 个事件, 当前EPS: 2662582.47
Strand 2: 已处理 28500000 个事件, 当前EPS: 2238454.29
Strand 0: 已处理 33900000 个事件, 当前EPS: 2659032.08
Strand 3: 已处理 28000000 个事件, 当前EPS: 2195906.20
Strand 1: 已处理 34000000 个事件, 当前EPS: 2665412.35
Strand 2: 已处理 28600000 个事件, 当前EPS: 2240325.87
Strand 0: 已处理 34000000 个事件, 当前EPS: 2661448.14
Strand 3: 已处理 28100000 个事件, 当前EPS: 2198576.01
Strand 1: 已处理 34100000 个事件, 当前EPS: 2667605.41
Strand 2: 已处理 28700000 个事件, 当前EPS: 2242713.14
Strand 0: 已处理 34100000 个事件, 当前EPS: 2663854.39
Strand 1: 已处理 34200000 个事件, 当前EPS: 2669997.66
Strand 3: 已处理 28200000 个事件, 当前EPS: 2200717.96
Strand 0: 已处理 34200000 个事件, 当前EPS: 2666043.03
Strand 2: 已处理 28800000 个事件, 当前EPS: 2244913.87
Strand 1: 已处理 34300000 个事件, 当前EPS: 2672172.02
Strand 3: 已处理 28300000 个事件, 当前EPS: 2203020.40
Strand 0: 已处理 34300000 个事件, 当前EPS: 2668430.06
Strand 2: 已处理 28900000 个事件, 当前EPS: 2247103.65
Strand 1: 已处理 34400000 个事件, 当前EPS: 2674545.17
Strand 3: 已处理 28400000 个事件, 当前EPS: 2205311.38
Strand 0: 已处理 34400000 个事件, 当前EPS: 2670600.11
Strand 1: 已处理 34500000 个事件, 当前EPS: 2676701.06
Strand 2: 已处理 29000000 个事件, 当前EPS: 2249457.03
Strand 0: 已处理 34500000 个事件, 当前EPS: 2672968.16
Strand 3: 已处理 28500000 个事件, 当前EPS: 2207591.01
Strand 1: 已处理 34600000 个事件, 当前EPS: 2679055.36
Strand 2: 已处理 29100000 个事件, 当前EPS: 2251624.88
Strand 0: 已处理 34600000 个事件, 当前EPS: 2675119.84
Strand 1: 已处理 34700000 个事件, 当前EPS: 2681400.20
Strand 3: 已处理 28600000 个事件, 当前EPS: 2209859.37
Strand 2: 已处理 29200000 个事件, 当前EPS: 2253782.03
Strand 0: 已处理 34700000 个事件, 当前EPS: 2677469.14
Strand 1: 已处理 34800000 个事件, 当前EPS: 2683735.64
Strand 3: 已处理 28700000 个事件, 当前EPS: 2211775.59
Strand 2: 已处理 29300000 个事件, 当前EPS: 2256275.99
Strand 0: 已处理 34800000 个事件, 当前EPS: 2679602.68
Strand 1: 已处理 34900000 个事件, 当前EPS: 2685855.01
=== 每秒性能统计 ===
Strand 0: 本秒处理: 3767915 事件, EPS: 3767915.00, 累计: 34852807, 连续性错误: 0
Strand 1: 本秒处理: 3770002 事件, EPS: 3770002.00, 累计: 34924115, 连续性错误: 0
Strand 2: 本秒处理: 3159130 事件, EPS: 3159130.00, 累计: 29344085, 连续性错误: 0
Strand 3: 本秒处理: 3111425 事件, EPS: 3111425.00, 累计: 28773434, 连续性错误: 0
Strand 3: 已处理 28800000 个事件, 当前EPS: 2214022.14
Strand 0: 已处理 34900000 个事件, 当前EPS: 2681933.45
Strand 2: 已处理 29400000 个事件, 当前EPS: 2258411.43
Strand 1: 已处理 35000000 个事件, 当前EPS: 2688172.04
Strand 0: 已处理 35000000 个事件, 当前EPS: 2684049.08
Strand 3: 已处理 28900000 个事件, 当前EPS: 2216087.72
Strand 1: 已处理 35100000 个事件, 当前EPS: 2690273.63
Strand 2: 已处理 29500000 个事件, 当前EPS: 2260536.40
Strand 0: 已处理 35100000 个事件, 当前EPS: 2686361.55
Strand 3: 已处理 29000000 个事件, 当前EPS: 2218312.55
Strand 1: 已处理 35200000 个事件, 当前EPS: 2692572.48
Strand 2: 已处理 29600000 个事件, 当前EPS: 2262823.94
Strand 0: 已处理 35200000 个事件, 当前EPS: 2688870.22
Strand 1: 已处理 35300000 个事件, 当前EPS: 2693833.94
Strand 3: 已处理 29100000 个事件, 当前EPS: 2220865.45
Strand 2: 已处理 29700000 个事件, 当前EPS: 2265100.67
Strand 0: 已处理 35300000 个事件, 当前EPS: 2691164.14
Strand 1: 已处理 35400000 个事件, 当前EPS: 2696115.77
Strand 3: 已处理 29200000 个事件, 当前EPS: 2222898.90
Strand 2: 已处理 29800000 个事件, 当前EPS: 2267366.66
Strand 0: 已处理 35400000 个事件, 当前EPS: 2692629.50
Strand 1: 已处理 35500000 个事件, 当前EPS: 2698593.69
Strand 3: 已处理 29300000 个事件, 当前EPS: 2225260.12
Strand 0: 已处理 35500000 个事件, 当前EPS: 2694701.69
Strand 2: 已处理 29900000 个事件, 当前EPS: 2269621.98
Strand 1: 已处理 35600000 个事件, 当前EPS: 2700652.40
Strand 3: 已处理 29400000 个事件, 当前EPS: 2227779.04
Strand 0: 已处理 35600000 个事件, 当前EPS: 2696969.70
Strand 1: 已处理 35700000 个事件, 当前EPS: 2703111.99
Strand 2: 已处理 30000000 个事件, 当前EPS: 2271178.74
Strand 0: 已处理 35700000 个事件, 当前EPS: 2699228.79
Strand 3: 已处理 29500000 个事件, 当前EPS: 2229949.35
Strand 1: 已处理 35800000 个事件, 当前EPS: 2705153.39
Strand 2: 已处理 30100000 个事件, 当前EPS: 2273413.90
Strand 0: 已处理 35800000 个事件, 当前EPS: 2701275.18
Strand 1: 已处理 35900000 个事件, 当前EPS: 2707390.65
Strand 3: 已处理 29600000 个事件, 当前EPS: 2232109.19
Strand 2: 已处理 30200000 个事件, 当前EPS: 2275467.15
Strand 0: 已处理 35900000 个事件, 当前EPS: 2703516.83
Strand 1: 已处理 36000000 个事件, 当前EPS: 2709619.15
Strand 3: 已处理 29700000 个事件, 当前EPS: 2233754.51
Strand 2: 已处理 30300000 个事件, 当前EPS: 2277681.73
Strand 0: 已处理 36000000 个事件, 当前EPS: 2705749.72
Strand 1: 已处理 36100000 个事件, 当前EPS: 2711635.24
Strand 3: 已处理 29800000 个事件, 当前EPS: 2235894.36
Strand 0: 已处理 36100000 个事件, 当前EPS: 2707770.78
Strand 2: 已处理 30400000 个事件, 当前EPS: 2279886.01
Strand 1: 已处理 36200000 个事件, 当前EPS: 2713846.62
Strand 0: 已处理 36200000 个事件, 当前EPS: 2709783.67
Strand 3: 已处理 29900000 个事件, 当前EPS: 2238023.95
Strand 1: 已处理 36300000 个事件, 当前EPS: 2715846.18
Strand 2: 已处理 30500000 个事件, 当前EPS: 2281909.32
Strand 0: 已处理 36300000 个事件, 当前EPS: 2711991.03
Strand 1: 已处理 36400000 个事件, 当前EPS: 2718040.62
Strand 3: 已处理 30000000 个事件, 当前EPS: 2240143.37
Strand 2: 已处理 30600000 个事件, 当前EPS: 2283922.97
Strand 0: 已处理 36400000 个事件, 当前EPS: 2713987.47
Strand 1: 已处理 36500000 个事件, 当前EPS: 2720023.85
Strand 3: 已处理 30100000 个事件, 当前EPS: 2242252.68
Strand 2: 已处理 30700000 个事件, 当前EPS: 2286097.25
Strand 0: 已处理 36500000 个事件, 当前EPS: 2716178.00
Strand 1: 已处理 36600000 个事件, 当前EPS: 2722201.56
Strand 3: 已处理 30200000 个事件, 当前EPS: 2244351.96
Strand 2: 已处理 30800000 个事件, 当前EPS: 2288091.52
Strand 0: 已处理 36600000 个事件, 当前EPS: 2718158.19
Strand 1: 已处理 36700000 个事件, 当前EPS: 2724168.65
Strand 3: 已处理 30300000 个事件, 当前EPS: 2246441.28
Strand 0: 已处理 36700000 个事件, 当前EPS: 2720332.07
Strand 2: 已处理 30900000 个事件, 当前EPS: 2290076.34
Strand 1: 已处理 36800000 个事件, 当前EPS: 2726329.83
Strand 0: 已处理 36800000 个事件, 当前EPS: 2722497.60
Strand 3: 已处理 30400000 个事件, 当前EPS: 2248520.71
Strand 2: 已处理 31000000 个事件, 当前EPS: 2292221.24
Strand 1: 已处理 36900000 个事件, 当前EPS: 2727877.58
Strand 0: 已处理 36900000 个事件, 当前EPS: 2724252.49
Strand 3: 已处理 30500000 个事件, 当前EPS: 2250756.40
Strand 1: 已处理 37000000 个事件, 当前EPS: 2730022.87
Strand 2: 已处理 31100000 个事件, 当前EPS: 2294356.33
Strand 0: 已处理 37000000 个事件, 当前EPS: 2726201.00
Strand 1: 已处理 37100000 个事件, 当前EPS: 2732159.95
Strand 3: 已处理 30600000 个事件, 当前EPS: 2252816.02
Strand 2: 已处理 31200000 个事件, 当前EPS: 2296481.67
Strand 0: 已处理 37100000 个事件, 当前EPS: 2728342.40
Strand 1: 已处理 37200000 个事件, 当前EPS: 2734087.90
Strand 3: 已处理 30700000 个事件, 当前EPS: 2254865.96
Strand 2: 已处理 31300000 个事件, 当前EPS: 2298428.55
Strand 0: 已处理 37200000 个事件, 当前EPS: 2730275.23
Strand 1: 已处理 37300000 个事件, 当前EPS: 2736409.65
Strand 3: 已处理 30800000 个事件, 当前EPS: 2256740.91
Strand 0: 已处理 37300000 个事件, 当前EPS: 2732600.73
Strand 2: 已处理 31400000 个事件, 当前EPS: 2300029.30
Strand 1: 已处理 37400000 个事件, 当前EPS: 2738522.37
Strand 0: 已处理 37400000 个事件, 当前EPS: 2734717.75
Strand 3: 已处理 30900000 个事件, 当前EPS: 2258771.93
Strand 2: 已处理 31500000 个事件, 当前EPS: 2302126.73
Strand 1: 已处理 37500000 个事件, 当前EPS: 2740426.78
Strand 0: 已处理 37500000 个事件, 当前EPS: 2736627.02
Strand 1: 已处理 37600000 个事件, 当前EPS: 2742523.71
Strand 3: 已处理 31000000 个事件, 当前EPS: 2260793.47
Strand 2: 已处理 31600000 个事件, 当前EPS: 2304046.66
Strand 0: 已处理 37600000 个事件, 当前EPS: 2738728.24
Strand 1: 已处理 37700000 个事件, 当前EPS: 2744612.70
Strand 2: 已处理 31700000 个事件, 当前EPS: 2306293.20
Strand 3: 已处理 31100000 个事件, 当前EPS: 2262640.96
Strand 0: 已处理 37700000 个事件, 当前EPS: 2740024.71
Strand 1: 已处理 37800000 个事件, 当前EPS: 2746693.79
Strand 2: 已处理 31800000 个事件, 当前EPS: 2308194.82
Strand 3: 已处理 31200000 个事件, 当前EPS: 2264643.97
Strand 0: 已处理 37800000 个事件, 当前EPS: 2742110.99
Strand 1: 已处理 37900000 个事件, 当前EPS: 2747969.84
Strand 3: 已处理 31300000 个事件, 当前EPS: 2266966.03
Strand 0: 已处理 37900000 个事件, 当前EPS: 2744586.86
Strand 2: 已处理 31900000 个事件, 当前EPS: 2309920.35
Strand 1: 已处理 38000000 个事件, 当前EPS: 2750036.18
Strand 0: 已处理 38000000 个事件, 当前EPS: 2746458.51
Strand 3: 已处理 31400000 个事件, 当前EPS: 2268950.07
Strand 2: 已处理 32000000 个事件, 当前EPS: 2311804.65
Strand 1: 已处理 38100000 个事件, 当前EPS: 2752094.77
Strand 0: 已处理 38100000 个事件, 当前EPS: 2748322.87
Strand 1: 已处理 38200000 个事件, 当前EPS: 2753947.08
Strand 3: 已处理 31500000 个事件, 当前EPS: 2270924.95
Strand 2: 已处理 32100000 个事件, 当前EPS: 2313847.04
Strand 0: 已处理 38200000 个事件, 当前EPS: 2750378.00
Strand 1: 已处理 38300000 个事件, 当前EPS: 2755792.20
Strand 3: 已处理 31600000 个事件, 当前EPS: 2272890.74
Strand 2: 已处理 32200000 个事件, 当前EPS: 2315713.77
Strand 0: 已处理 38300000 个事件, 当前EPS: 2752227.65
Strand 1: 已处理 38400000 个事件, 当前EPS: 2757630.16
Strand 3: 已处理 31700000 个事件, 当前EPS: 2274847.51
Strand 2: 已处理 32300000 个事件, 当前EPS: 2317571.93
Strand 0: 已处理 38400000 个事件, 当前EPS: 2754267.68
Strand 1: 已处理 38500000 个事件, 当前EPS: 2759658.81
Strand 3: 已处理 31800000 个事件, 当前EPS: 2276795.30
Strand 2: 已处理 32400000 个事件, 当前EPS: 2319421.58
Strand 0: 已处理 38500000 个事件, 当前EPS: 2756102.80
Strand 1: 已处理 38600000 个事件, 当前EPS: 2761482.33
Strand 0: 已处理 38600000 个事件, 当前EPS: 2758127.90
Strand 3: 已处理 31900000 个事件, 当前EPS: 2278734.20
Strand 2: 已处理 32500000 个事件, 当前EPS: 2321428.57
=== 每秒性能统计 ===
Strand 0: 本秒处理: 3766666 事件, EPS: 3766666.00, 累计: 38619480, 连续性错误: 0
Strand 1: 本秒处理: 3762350 事件, EPS: 3762350.00, 累计: 38686463, 连续性错误: 0
Strand 2: 本秒处理: 3156392 事件, EPS: 3156392.00, 累计: 32500476, 连续性错误: 0
Strand 3: 本秒处理: 3128331 事件, EPS: 3128331.00, 累计: 31901766, 连续性错误: 0
Strand 1: 已处理 38700000 个事件, 当前EPS: 2763496.14
Strand 0: 已处理 38700000 个事件, 当前EPS: 2759948.65
Strand 1: 已处理 38800000 个事件, 当前EPS: 2765502.49
Strand 3: 已处理 32000000 个事件, 当前EPS: 2280501.71
Strand 2: 已处理 32600000 个事件, 当前EPS: 2323261.12
Strand 0: 已处理 38800000 个事件, 当前EPS: 2761959.00
Strand 1: 已处理 38900000 个事件, 当前EPS: 2767501.42
Strand 2: 已处理 32700000 个事件, 当前EPS: 2325416.01
Strand 3: 已处理 32100000 个事件, 当前EPS: 2282098.68
Strand 0: 已处理 38900000 个事件, 当前EPS: 2763765.54
Strand 1: 已处理 39000000 个事件, 当前EPS: 2769296.31
Strand 2: 已处理 32800000 个事件, 当前EPS: 2327231.45
Strand 3: 已处理 32200000 个事件, 当前EPS: 2283849.92
Strand 0: 已处理 39000000 个事件, 当前EPS: 2765761.29
Strand 1: 已处理 39100000 个事件, 当前EPS: 2771280.74
Strand 2: 已处理 32900000 个事件, 当前EPS: 2329203.54
Strand 3: 已处理 32300000 个事件, 当前EPS: 2285916.49
Strand 0: 已处理 39100000 个事件, 当前EPS: 2766966.24
Strand 1: 已处理 39200000 个事件, 当前EPS: 2773454.08
Strand 2: 已处理 33000000 个事件, 当前EPS: 2331167.00
Strand 0: 已处理 39200000 个事件, 当前EPS: 2768752.65
Strand 1: 已处理 39300000 个事件, 当前EPS: 2775227.74
Strand 3: 已处理 32400000 个事件, 当前EPS: 2287812.46
Strand 0: 已处理 39300000 个事件, 当前EPS: 2770727.58
Strand 1: 已处理 39400000 个事件, 当前EPS: 2777190.39
Strand 2: 已处理 33100000 个事件, 当前EPS: 2332957.43
Strand 3: 已处理 32500000 个事件, 当前EPS: 2289699.87
Strand 0: 已处理 39400000 个事件, 当前EPS: 2772500.18
Strand 1: 已处理 39500000 个事件, 当前EPS: 2778950.33
Strand 2: 已处理 33200000 个事件, 当前EPS: 2334904.00
Strand 3: 已处理 32600000 个事件, 当前EPS: 2291578.80
Strand 0: 已处理 39500000 个事件, 当前EPS: 2774655.80
Strand 1: 已处理 39600000 个事件, 当前EPS: 2780313.14
Strand 2: 已处理 33300000 个事件, 当前EPS: 2336350.24
Strand 3: 已处理 32700000 个事件, 当前EPS: 2293931.95
Strand 0: 已处理 39600000 个事件, 当前EPS: 2776609.17
Strand 1: 已处理 39700000 个事件, 当前EPS: 2782060.27
Strand 2: 已处理 33400000 个事件, 当前EPS: 2338280.59
Strand 3: 已处理 32800000 个事件, 当前EPS: 2295793.38
Strand 0: 已处理 39700000 个事件, 当前EPS: 2778555.43
Strand 1: 已处理 39800000 个事件, 当前EPS: 2783995.52
Strand 0: 已处理 39800000 个事件, 当前EPS: 2780300.38
Strand 2: 已处理 33500000 个事件, 当前EPS: 2340039.12
Strand 3: 已处理 32900000 个事件, 当前EPS: 2297646.48
Strand 1: 已处理 39900000 个事件, 当前EPS: 2785729.25
Strand 0: 已处理 39900000 个事件, 当前EPS: 2782232.76
Strand 2: 已处理 33600000 个事件, 当前EPS: 2341789.80
Strand 3: 已处理 33000000 个事件, 当前EPS: 2299491.32
Strand 2: 已处理 33700000 个事件, 当前EPS: 2345489.98
Strand 3: 已处理 33100000 个事件, 当前EPS: 2303409.88
Strand 2: 已处理 33800000 个事件, 当前EPS: 2349833.15
Strand 3: 已处理 33200000 个事件, 当前EPS: 2307799.25
Strand 1 完成!
总时间: 14394ms
平均每秒: 2778935.67 事件
Strand 2: 已处理 33900000 个事件, 当前EPS: 2354330.16
Strand 3: 已处理 33300000 个事件, 当前EPS: 2311536.86
Strand 2: 已处理 34000000 个事件, 当前EPS: 2359472.59
Strand 0 完成!
总时间: 14418ms
平均每秒: 2774309.89 事件
Strand 3: 已处理 33400000 个事件, 当前EPS: 2315906.25
Strand 2: 已处理 34100000 个事件, 当前EPS: 2363787.61
Strand 3: 已处理 33500000 个事件, 当前EPS: 2320265.96
Strand 2: 已处理 34200000 个事件, 当前EPS: 2368257.05
Strand 3: 已处理 33600000 个事件, 当前EPS: 2324616.02
Strand 2: 已处理 34300000 个事件, 当前EPS: 2372553.09
Strand 3: 已处理 33700000 个事件, 当前EPS: 2328956.46
Strand 2: 已处理 34400000 个事件, 当前EPS: 2376839.63
Strand 3: 已处理 33800000 个事件, 当前EPS: 2333287.31
Strand 2: 已处理 34500000 个事件, 当前EPS: 2381116.71
Strand 3: 已处理 33900000 个事件, 当前EPS: 2337608.61
Strand 2: 已处理 34600000 个事件, 当前EPS: 2385384.35
Strand 3: 已处理 34000000 个事件, 当前EPS: 2341920.37
Strand 2: 已处理 34700000 个事件, 当前EPS: 2389807.16
Strand 3: 已处理 34100000 个事件, 当前EPS: 2346222.65
Strand 2: 已处理 34800000 个事件, 当前EPS: 2394056.14
Strand 3: 已处理 34200000 个事件, 当前EPS: 2351646.84
Strand 2: 已处理 34900000 个事件, 当前EPS: 2397636.71
Strand 3: 已处理 34300000 个事件, 当前EPS: 2355931.04
Strand 2: 已处理 35000000 个事件, 当前EPS: 2401866.59
Strand 3: 已处理 34400000 个事件, 当前EPS: 2360205.83
Strand 2: 已处理 35100000 个事件, 当前EPS: 2406252.14
Strand 3: 已处理 34500000 个事件, 当前EPS: 2364471.25
Strand 2: 已处理 35200000 个事件, 当前EPS: 2410958.90
Strand 3: 已处理 34600000 个事件, 当前EPS: 2368240.93
Strand 2: 已处理 35300000 个事件, 当前EPS: 2415657.29
Strand 3: 已处理 34700000 个事件, 当前EPS: 2372487.35
Strand 2: 已处理 35400000 个事件, 当前EPS: 2419850.98
Strand 3: 已处理 34800000 个事件, 当前EPS: 2376724.49
Strand 2: 已处理 35500000 个事件, 当前EPS: 2424035.51
Strand 3: 已处理 34900000 个事件, 当前EPS: 2380789.96
Strand 2: 已处理 35600000 个事件, 当前EPS: 2428210.90
Strand 3: 已处理 35000000 个事件, 当前EPS: 2385008.52
Strand 2: 已处理 35700000 个事件, 当前EPS: 2432377.19
Strand 3: 已处理 35100000 个事件, 当前EPS: 2389217.89
Strand 2: 已处理 35800000 个事件, 当前EPS: 2436534.40
Strand 3: 已处理 35200000 个事件, 当前EPS: 2393418.10
Strand 2: 已处理 35900000 个事件, 当前EPS: 2440848.52
Strand 3: 已处理 35300000 个事件, 当前EPS: 2397609.18
Strand 2: 已处理 36000000 个事件, 当前EPS: 2444987.78
Strand 3: 已处理 35400000 个事件, 当前EPS: 2401791.17
Strand 2: 已处理 36100000 个事件, 当前EPS: 2449118.05
Strand 3: 已处理 35500000 个事件, 当前EPS: 2405964.08
Strand 2: 已处理 36200000 个事件, 当前EPS: 2453239.36
Strand 3: 已处理 35600000 个事件, 当前EPS: 2410127.95
Strand 2: 已处理 36300000 个事件, 当前EPS: 2457518.11
Strand 2: 已处理 36400000 个事件, 当前EPS: 2461621.69
Strand 3: 已处理 35700000 个事件, 当前EPS: 2414282.82
Strand 2: 已处理 36500000 个事件, 当前EPS: 2465716.41
Strand 3: 已处理 35800000 个事件, 当前EPS: 2418428.70
Strand 2: 已处理 36600000 个事件, 当前EPS: 2470802.67
Strand 3: 已处理 35900000 个事件, 当前EPS: 2422075.29
Strand 2: 已处理 36700000 个事件, 当前EPS: 2475047.21
Strand 3: 已处理 36000000 个事件, 当前EPS: 2426857.22
Strand 2: 已处理 36800000 个事件, 当前EPS: 2478615.21
Strand 3: 已处理 36100000 个事件, 当前EPS: 2430976.43
Strand 2: 已处理 36900000 个事件, 当前EPS: 2482842.15
Strand 3: 已处理 36200000 个事件, 当前EPS: 2435086.78
Strand 2: 已处理 37000000 个事件, 当前EPS: 2486893.40
Strand 3: 已处理 36300000 个事件, 当前EPS: 2439188.28
Strand 2: 已处理 37100000 个事件, 当前EPS: 2490935.95
Strand 3: 已处理 36400000 个事件, 当前EPS: 2443116.99
Strand 2: 已处理 37200000 个事件, 当前EPS: 2494969.82
Strand 3: 已处理 36500000 个事件, 当前EPS: 2447200.80
Strand 2: 已处理 37300000 个事件, 当前EPS: 2498995.04
Strand 3: 已处理 36600000 个事件, 当前EPS: 2451275.87
Strand 2: 已处理 37400000 个事件, 当前EPS: 2503179.17
Strand 3: 已处理 36700000 个事件, 当前EPS: 2455506.49
Strand 3: 已处理 36800000 个事件, 当前EPS: 2460057.49
Strand 2: 已处理 37500000 个事件, 当前EPS: 2506852.06
Strand 2: 已处理 37600000 个事件, 当前EPS: 2510851.42
Strand 3: 已处理 36900000 个事件, 当前EPS: 2464106.84
Strand 2: 已处理 37700000 个事件, 当前EPS: 2514842.24
Strand 3: 已处理 37000000 个事件, 当前EPS: 2468147.56
=== 每秒性能统计 ===
Strand 0: 本秒处理: 1380555 事件, EPS: 1380555.00, 累计: 40000000, 连续性错误: 0
Strand 1: 本秒处理: 1313542 事件, EPS: 1313542.00, 累计: 40000000, 连续性错误: 0
Strand 2: 本秒处理: 5260620 事件, EPS: 5260620.00, 累计: 37761099, 连续性错误: 0
Strand 3: 本秒处理: 5157269 事件, EPS: 5157269.00, 累计: 37059038, 连续性错误: 0
Strand 2: 已处理 37800000 个事件, 当前EPS: 2518824.55
Strand 3: 已处理 37100000 个事件, 当前EPS: 2472179.65
Strand 2: 已处理 37900000 个事件, 当前EPS: 2523302.26
Strand 3: 已处理 37200000 个事件, 当前EPS: 2476038.34
Strand 2: 已处理 38000000 个事件, 当前EPS: 2527267.89
Strand 3: 已处理 37300000 个事件, 当前EPS: 2480053.19
Strand 2: 已处理 38100000 个事件, 当前EPS: 2531225.09
Strand 3: 已处理 37400000 个事件, 当前EPS: 2484059.51
Strand 2: 已处理 38200000 个事件, 当前EPS: 2535173.88
Strand 3: 已处理 37500000 个事件, 当前EPS: 2487562.19
Strand 2: 已处理 38300000 个事件, 当前EPS: 2539956.23
Strand 3: 已处理 37600000 个事件, 当前EPS: 2491551.26
Strand 2: 已处理 38400000 个事件, 当前EPS: 2544057.24
Strand 3: 已处理 37700000 个事件, 当前EPS: 2495531.87
Strand 2: 已处理 38500000 个事件, 当前EPS: 2547981.47
Strand 3: 已处理 37800000 个事件, 当前EPS: 2499504.07
Strand 2: 已处理 38600000 个事件, 当前EPS: 2551897.40
Strand 3: 已处理 37900000 个事件, 当前EPS: 2503467.86
Strand 2: 已处理 38700000 个事件, 当前EPS: 2555805.05
Strand 3: 已处理 38000000 个事件, 当前EPS: 2507588.76
Strand 2: 已处理 38800000 个事件, 当前EPS: 2559029.15
Strand 3: 已处理 38100000 个事件, 当前EPS: 2512861.10
Strand 2: 已处理 38900000 个事件, 当前EPS: 2562920.02
Strand 3: 已处理 38200000 个事件, 当前EPS: 2516800.63
Strand 2: 已处理 39000000 个事件, 当前EPS: 2566802.69
Strand 3: 已处理 38300000 个事件, 当前EPS: 2520731.87
Strand 2: 已处理 39100000 个事件, 当前EPS: 2570677.19
Strand 3: 已处理 38400000 个事件, 当前EPS: 2524654.83
Strand 2: 已处理 39200000 个事件, 当前EPS: 2574712.64
Strand 3: 已处理 38500000 个事件, 当前EPS: 2528569.55
Strand 2: 已处理 39300000 个事件, 当前EPS: 2578570.96
Strand 3: 已处理 38600000 个事件, 当前EPS: 2532476.05
Strand 2: 已处理 39400000 个事件, 当前EPS: 2582421.18
Strand 3: 已处理 38700000 个事件, 当前EPS: 2536374.36
Strand 2: 已处理 39500000 个事件, 当前EPS: 2586263.34
Strand 3: 已处理 38800000 个事件, 当前EPS: 2540264.50
Strand 2: 已处理 39600000 个事件, 当前EPS: 2590436.32
Strand 3: 已处理 38900000 个事件, 当前EPS: 2543481.10
Strand 2: 已处理 39700000 个事件, 当前EPS: 2595110.47
Strand 3: 已处理 39000000 个事件, 当前EPS: 2547354.67
Strand 2: 已处理 39800000 个事件, 当前EPS: 2598929.08
Strand 3: 已处理 39100000 个事件, 当前EPS: 2551220.15
Strand 2: 已处理 39900000 个事件, 当前EPS: 2602739.73
Strand 3: 已处理 39200000 个事件, 当前EPS: 2555077.56
Strand 3: 已处理 39300000 个事件, 当前EPS: 2560260.59
Strand 3: 已处理 39400000 个事件, 当前EPS: 2565772.34
Strand 3: 已处理 39500000 个事件, 当前EPS: 2571447.17
Strand 3: 已处理 39600000 个事件, 当前EPS: 2576950.61
Strand 3: 已处理 39700000 个事件, 当前EPS: 2582617.75
Strand 3: 已处理 39800000 个事件, 当前EPS: 2588112.89
Strand 2 完成!
总时间: 15381ms
平均每秒: 2600611.14 事件
Strand 3: 已处理 39900000 个事件, 当前EPS: 2593772.35
Strand 3 完成!
总时间: 15424ms
平均每秒: 2593361.00 事件
=== 每秒性能统计 ===
Strand 0: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
Strand 1: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
Strand 2: 本秒处理: 2238907 事件, EPS: 2238907.00, 累计: 40000000, 连续性错误: 0
Strand 3: 本秒处理: 2940968 事件, EPS: 2940968.00, 累计: 40000000, 连续性错误: 0
=== 每秒性能统计 ===
Strand 0: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
Strand 1: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
Strand 2: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
Strand 3: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
=== 每秒性能统计 ===
Strand 0: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
Strand 1: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
Strand 2: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
Strand
测试完成!
3: 本秒处理: 0 事件, EPS: 0.00, 累计: 40000000, 连续性错误: 0
=== 最终统计结果 ===
Strand 0 统计:
总处理事件数: 40000000
连续性错误数: 0
性能统计:
最小EPS: 0
最大EPS: 3769995
平均EPS: 2222218
✅ 连续性测试通过!
Strand 1 统计:
总处理事件数: 40000000
连续性错误数: 0
性能统计:
最小EPS: 0
最大EPS: 3776200
平均EPS: 2222218
✅ 连续性测试通过!
Strand 2 统计:
总处理事件数: 40000000
连续性错误数: 0
性能统计:
最小EPS: 0
最大EPS: 5260620
平均EPS: 2222219
✅ 连续性测试通过!
Strand 3 统计:
总处理事件数: 40000000
连续性错误数: 0
性能统计:
最小EPS: 0
最大EPS: 5157269
平均EPS: 2222219
✅ 连续性测试通过!
=== 全局统计 ===
总处理事件数: 160000000
总连续性错误: 0
平均每秒事件数: 8888888
[1] + Done                       "/usr/bin/gdb" --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-posunkj2.iw5" 1>"/tmp/Microsoft-MIEngine-Out-0hgcp2ss.hci"
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# cat ^C
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# cat /proc/cpuinfo
  processor       : 0
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2100.000
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 0
  cpu cores       : 12
  apicid          : 0
  initial apicid  : 0
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 1
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2100.000
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 4
  cpu cores       : 12
  apicid          : 8
  initial apicid  : 8
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 2
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2100.000
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 8
  cpu cores       : 12
  apicid          : 16
  initial apicid  : 16
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 3
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2100.000
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 12
  cpu cores       : 12
  apicid          : 24
  initial apicid  : 24
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 4
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2086.325
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 16
  cpu cores       : 12
  apicid          : 32
  initial apicid  : 32
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 5
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2100.000
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 20
  cpu cores       : 12
  apicid          : 40
  initial apicid  : 40
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 6
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2100.000
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 24
  cpu cores       : 12
  apicid          : 48
  initial apicid  : 48
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 7
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2099.999
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 28
  cpu cores       : 12
  apicid          : 56
  initial apicid  : 56
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 8
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 1599.985
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 36
  cpu cores       : 12
  apicid          : 72
  initial apicid  : 72
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 9
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2100.000
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 37
  cpu cores       : 12
  apicid          : 74
  initial apicid  : 74
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 10
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 1600.160
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 38
  cpu cores       : 12
  apicid          : 76
  initial apicid  : 76
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  processor       : 11
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 151
  model name      : 12th Gen Intel(R) Core(TM) i7-12700
  stepping        : 2
  microcode       : 0x3a
  cpu MHz         : 2100.000
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 12
  core id         : 39
  cpu cores       : 12
  apicid          : 78
  initial apicid  : 78
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 32
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr flush_l1d arch_capabilities ibpb_exit_to_user
  vmx flags       : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs ept_mode_based_exec tsc_scaling usr_wait_pause
  bugs            : spectre_v1 spectre_v2 spec_store_bypass swapgs eibrs_pbrsb rfds bhi vmscape
  bogomips        : 4224.00
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# cat /proc/meminfo
  bin/            build/          CMakeLists.txt  LinkedList.h    main.cpp        .vscode/
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# cat /proc/meminfo
  MemTotal:       65525976 kB
  MemFree:        43675060 kB
  MemAvailable:   55442136 kB
  Buffers:          534320 kB
  Cached:         11583168 kB
  SwapCached:            0 kB
  Active:          4522956 kB
  Inactive:       16314224 kB
  Active(anon):      33416 kB
  Inactive(anon):  8718152 kB
  Active(file):    4489540 kB
  Inactive(file):  7596072 kB
  Unevictable:       47424 kB
  Mlocked:           27812 kB
  SwapTotal:       8388604 kB
  SwapFree:        8388604 kB
  Dirty:                28 kB
  Writeback:             0 kB
  AnonPages:       8767148 kB
  Mapped:           565056 kB
  Shmem:             11892 kB
  KReclaimable:     411360 kB
  Slab:             563568 kB
  SReclaimable:     411360 kB
  SUnreclaim:       152208 kB
  KernelStack:       12304 kB
  PageTables:        59312 kB
  NFS_Unstable:          0 kB
  Bounce:                0 kB
  WritebackTmp:          0 kB
  CommitLimit:    41151592 kB
  Committed_AS:   11826972 kB
  VmallocTotal:   34359738367 kB
  VmallocUsed:       37292 kB
  VmallocChunk:          0 kB
  Percpu:            12608 kB
  HardwareCorrupted:     0 kB
  AnonHugePages:         0 kB
  ShmemHugePages:        0 kB
  ShmemPmdMapped:        0 kB
  FileHugePages:         0 kB
  FilePmdMapped:         0 kB
  HugePages_Total:       0
  HugePages_Free:        0
  HugePages_Rsvd:        0
  HugePages_Surp:        0
  Hugepagesize:       2048 kB
  Hugetlb:               0 kB
  DirectMap4k:      496756 kB
  DirectMap2M:    10719232 kB
  DirectMap1G:    56623104 kB
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# cat /proc/meminfo | grep MHz
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# sudo lshw -class memory | grep speed
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# /proc/meminfo ^C
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# ^C
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# ^C
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# cat /proc/meminfo
  MemTotal:       65525976 kB
  MemFree:        43668516 kB
  MemAvailable:   55438956 kB
  Buffers:          534472 kB
  Cached:         11586108 kB
  SwapCached:            0 kB
  Active:          4523108 kB
  Inactive:       16318456 kB
  Active(anon):      33416 kB
  Inactive(anon):  8719448 kB
  Active(file):    4489692 kB
  Inactive(file):  7599008 kB
  Unevictable:       47424 kB
  Mlocked:           27812 kB
  SwapTotal:       8388604 kB
  SwapFree:        8388604 kB
  Dirty:                56 kB
  Writeback:             0 kB
  AnonPages:       8768464 kB
  Mapped:           565060 kB
  Shmem:             11892 kB
  KReclaimable:     411636 kB
  Slab:             563884 kB
  SReclaimable:     411636 kB
  SUnreclaim:       152248 kB
  KernelStack:       12304 kB
  PageTables:        59316 kB
  NFS_Unstable:          0 kB
  Bounce:                0 kB
  WritebackTmp:          0 kB
  CommitLimit:    41151592 kB
  Committed_AS:   11828004 kB
  VmallocTotal:   34359738367 kB
  VmallocUsed:       37308 kB
  VmallocChunk:          0 kB
  Percpu:            12608 kB
  HardwareCorrupted:     0 kB
  AnonHugePages:         0 kB
  ShmemHugePages:        0 kB
  ShmemPmdMapped:        0 kB
  FileHugePages:         0 kB
  FilePmdMapped:         0 kB
  HugePages_Total:       0
  HugePages_Free:        0
  HugePages_Rsvd:        0
  HugePages_Surp:        0
  Hugepagesize:       2048 kB
  Hugetlb:               0 kB
  DirectMap4k:      496756 kB
  DirectMap2M:    10719232 kB
  DirectMap1G:    56623104 kB
  root@test02:~/project/new/chtrader/app/csvcppcodegenerator# sudo dmidecode -t memory | grep -i speed
  Speed: 4800 MT/s
  Configured Memory Speed: 4400 MT/s
  Speed: 4800 MT/s
  Configured Memory Speed: 4400 MT/s
  Speed: Unknown
  Configured Memory Speed: Unknown
  Speed: Unknown
  Configured Memory Speed: Unknown
posted @ 2026-01-16 08:15  gccbuaa  阅读(3)  评论(0)    收藏  举报