优化栈遍历性能
Optimizing Stack-Walking performance
目前我使用dbghelp库来遍历一些进程线程的堆栈(使用GetThreadContext()和StackWalk64())并仅收集每个帧包含的返回地址。
然而,这样做的开销对于系统需求来说太大了——每次堆栈遍历的总时间是apx. 5毫秒(10-15帧)。这一次包括GetThreadContext()和调用StackWalk64()来获取所有帧的循环。
无论如何,我必须找到一种更快的方法来做这件事。有人知道怎么做吗?编辑:
有谁知道ETW (Windows事件跟踪)机制吗?
如果是,我如何跟踪在一段时间内发生的所有上下文切换?是否存在在每个上下文切换上发布事件的事件提供程序?
我能想到的最快的方法是通过创建一个内核驱动程序来创建您自己的GetThreadContext
和StackWalk64
版本,该内核驱动程序捕获您试图监视的线程的ETHREAD
结构的kernelStack
字段。这里有一篇关于这个主题的好文章。
如果你使用的是Windows Vista或更高版本,你应该使用ETW,句号。您可以激活所有您正在谈论的内容,包括上下文切换和样本配置文件事件,而且它非常有效。对于X86,它基本上是遍历EBP寄存器链,这是它需要遍历的地址链表。在64位领域,堆栈行走器必须展开堆栈,因此它的效率有点低,但我可以告诉您,如果您在应用程序中执行任何合理数量的工作,堆栈行走的影响就不会显示出来。当然不是毫秒级的
ETW部分实际上是一个独立的问题。Windows性能分析工具可以捕获所有上下文切换,以及Visual Studio Profiler在"资源争用并发分析"模式下。您还可以使用logman手动将所有事件转储到文件中,请参阅此处的说明。
相关文章:
- 有什么方法可以遍历结构吗
- 在循环中按顺序遍历成员变量
- 遍历模板参数
- 在遍历处理程序的向量时注册和注销处理程序
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 遍历并行数组以确定C++中的最大数字
- 遍历顺序由 std::文件系统directory_iterator给出
- 遍历链表时的无限循环
- 遍历unordered_map向量
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- C++声明双链表,使用两个 for 循环双向遍历列表并打印
- 如何正确地推回然后遍历堆中对象的向量?
- 遍历二维数组的所有子数组
- 如何在可变参数模板函数中遍历可变参数元组?
- 避免在遍历 IShellItemArray 时出现代码重复
- 从特定键开始遍历地图
- 关于链表遍历和调试的困惑
- 将树节点添加到向量向量中的 n 元树遍历的平均和最坏情况时间复杂度是多少?
- 为什么即使使用 for 循环遍历我的向量,它也没有输出到控制台?(C++)
- 优化栈遍历性能