【问题标题】:Profiling turned up _Iterator_base12::_Orphan_me. What is it?分析出现了_Iterator_base12::_Orphan_me。它是什么?
【发布时间】:2011-07-07 16:17:14
【问题描述】:

我刚刚完成了一段代码的分析,这占用了太多时间。有问题的代码从一些 std::vectors 和一个 std::set 创建了一个很大的 boost::graph,它们被排序并插入了很多次。然而,令我惊讶的是,大部分时间没有花在排序或插入上,而是花在std::_Iterator_base12::_Orphan_me - AMD CodeAnalyst 报告的 97.27% 上。这是什么功能?它似乎被调用了 ~2200 次,总运行时间是 ~30 秒。

CodeAnalyst 没有给我一个很好的调用堆栈,并且似乎在 120 个左右的字符之后剪切名称,这与 boost 模板类型不匹配。如果有办法改进这一点(我对 CodeAnalyst 还很陌生),请说出来,我可能会提供更好的信息。

【问题讨论】:

  • 您确定在分析之前以发布模式编译代码吗?与调试模式相比,许多底层迭代器机制在发布时得到了优化。
  • 在性能调优中,意外是意料之中的。程序是否在进行 I/O?如果是这样,那可能是 97%。无论如何,如果你想看看到底发生了什么,give this a try。
  • 迭代器已被制成非规范化的 bfd,带有指向其容器的反向指针。你可以关闭所有这些。 Check this out.
  • @Mike 和@Praetorian:谢谢!不,我没有切换到释放模式 (facepalm)。特别是。 Mike,链接的博客文章内容丰富。您介意将其发布为答案吗? (顺便说一句,切换到发布,更大问题的运行时间从 > 40 分钟减少到不到 2 秒......)

标签: c++ profiling


【解决方案1】:

答案是在Release模式下运行分析器,见performance killer -Debug Iterator Support in Visual studio。

由_SECURE_SCL 启用的迭代器检查执行最少的检查,作为安全防御的最后一道防线……因为它在发布模式下默认启用,力求将性能损失降到最低。因此,当它启用时,虽然迭代器有指向其容器的指针,但容器没有指向其迭代器的指针......

Orcas 中的 Swap Fix 使每个标准容器都拥有一个额外的动态分配对象,想象中地称为“aux 对象”。 每个容器都拥有一个指向其aux 对象的指针,该对象拥有一个返回容器的指针。每个迭代器,而不是直接持有指向其父容器的指针,现在持有指向其父容器的 aux 对象的指针...

性能问题是aux 对象,虽然不可避免... 不是免费的。每个标准容器现在都变大了,因为它必须保存一个指向其aux 对象的指针。 aux 对象必须动态分配,占用更多空间并花费更多时间。而_SECURE_SCL 在从迭代器到其父容器时执行了双重间接。

【讨论】:

  • 我遇到了相关的a question:Debug 模式下的正则表达式搜索操作在Orphan_me() 方法处引发了堆栈溢出异常。切换到 Release 解决了这个问题(并且使正则表达式模式更简单可能会有所帮助)。
猜你喜欢
  • 2011-01-13
  • 1970-01-01
  • 2010-09-19
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 2012-07-30
相关资源
最近更新 更多