为什么即使将_HAS_ITERATOR_debugging、_SECURE_SCL、_SECURE_SCL_THROWS

Why are iterators causing very slow debugging in VS2010 even with _HAS_ITERATOR_DEBUGGING, _SECURE_SCL, _SECURE_SCL_THROWS set to 0

本文关键字:SECURE SCL THROWS debugging HAS 为什么 ITERATOR      更新时间:2023-10-16

我一直在努力找出为什么在调试模式下调试程序需要这么长时间。在使用xperf查看堆栈的外观后,很明显,我们在迭代器和STL容器上花费了大量时间。我在谷歌上搜索了一段时间,找到了选项

_HAS_ITERATOR_DEBUGGING=0
_SECURE_SCL=0
_SECURE_SCL_THROWS=0

我用#define 在代码中设置了所有这些

#define _HAS_ITERATOR_DEBUGGING 0
#define _SECURE_SCL 0
#define _SECURE_SCL_THROWS 0

但这似乎不起作用,所以我在visual studio项目中使用预处理器定义进行了尝试,但似乎仍然没有帮助。

我已经尝试了我能想到的几乎每一种排列,包括在标头中设置它们,以及在所有包含之后,但无论我做什么,在调试时我都没有看到性能的提高。举个例子,当在释放模式下运行时,这一系列操作大约需要140秒。在调试模式下,它需要2400秒多一点的时间。处理时间大约增加了17-18倍。

一些附加信息,承载这些C++dll的进程是一个C#.net 4进程,并且我启用了非托管代码调试。基本上所有的过程都是为我们加载DLL。所有真正的工作都是在c++代码中完成的。

我在下面包含了完整的编译器命令行。

/I"..CommonInclude" /Zi /nologo /W4 /WX /Od /Oy- /D "_CRT_SECURE_NO_WARNINGS" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "ENGINE_EXPORTS" /D "_HAS_ITERATOR_DEBUGGING=0" /D "_SECURE_SCL=0" /D "_SECURE_SCL_THROWS=0" /D "_VC80_UPGRADE=0x0710" /D "_WINDLL" /D "_MBCS" /Gm- /EHa /MDd /GS /fp:precise /Zc:wchar_t- /Zc:forScope /GR /Yu"StdAfx.h" /Fp".Debug/Foo.pch" /Fa".Debug/" /Fo".Debug/" /Fd".Debug/" /Gd /analyze- /errorReport:queue /EHa -Zm350 /MP3 

有什么想法为什么会这么慢吗?

根据您的描述,这会立即跳出来:

我一直在努力找出为什么调试我们的当处于调试模式时程序。使用xperf查看看起来很明显,我们花了一大笔钱我们在迭代器和STL容器中的时间。

如果使用基于节点的容器(例如,mapsetunordered_mapunordered_setmultimapmultisetlist等)并从调试器运行,则可能会遇到由于这些容器分配了大量小对象而导致的问题。当您在Windows中从调试器运行应用程序时,操作系统会将进程堆切换到调试堆。如果加载了许多基于节点的容器,释放它们将占用调试堆的大量时间。

一个简单的修复方法是通过在调试选项的Environment部分添加以下内容来禁用调试堆:_NO_DEBUG_HEAP=1

这将禁用调试堆。

有一点非常不同,那就是默认情况下,函数在调试模式下不内联。这为使用许多小型访问器函数的代码增加了大量时间。

我有一些程序,调试模式和发布模式之间的差异是100倍以上,而不依赖于迭代器。

要尝试的几件事:

  • 使用探查器,例如免费的AMD CodeAnalyst,因为它会给你调用堆栈,而且通常比Xperf更容易使用。即使您正在处理调试代码,您仍然可能会发现一些热点
  • 创建一个关闭优化的版本构建(您可以为此创建一个单独的配置)。这将关闭迭代器调试(以防速度减慢),但可能会提供比原始版本更有用的调试信息。检查是否启用了"省略帧指针"选项