2

我遇到了一个问题,即 Win32 应用程序在调试和发布版本之间存在巨大的性能差异。发布需要 20 秒,而调试构建需要 6 分钟来初始化应用程序。这很痛苦,因为在调试时,在开始做任何事情之前进行初始化总是需要 6 分钟。所以我正在寻找一种方法来调整调试构建中的性能。

运行分析器后,我发现下面的代码是热点。

class CellList {
    std::vector<CellPtr>* _cells;
    iterator begin() { return (*_cells).begin(); }
    iterator end()   { return (*_cells).end(); }
    reverse_iterator rbegin() { return (*_cells).rbegin(); }
    reverse_iterator rend()   { return (*_cells).rend(); }
    ...
}

CellList _cellList = ...;

for (CellList::iterator itr = _cellList.begin(), end = _cellList.end(); itr < end; ++itr) {
  Cell* cell = *itr;
  if (cell->getFoo()) cell->setBar(true);
  else cell->setBar(false);
}

for (CellList::iterator itr = _cellList.rbegin(), end = _cellList.rend(); itr < end; ++itr) {
  Cell* cell = *itr;
  if (cell->getFoo2()) cell->setBar2(true);
  else cell->setBar2(false);
}

这些是时基剖面结果中的热点。

std::operator< <std::_Vector_iterator<Cell *,std::allocator<Cell *> >,std::_Vector_iterator<Cell *,std::allocator<Cell *> > >
std::_Vector_const_iterator<Cell *,std::allocator<Cell *> >::operator<
std::reverse_iterator<std::_Vector_iterator<Cell *,std::allocator<Cell *> > >::operator*
std::reverse_iterator<std::_Vector_const_iterator<Cell *,std::allocator<Cell *> > >::reverse_iterator<std::_Vector_const_iterator<Cell *,std::allocator<Cell *> > ><std::_Vector_iterator<Cell *,std::allocator<Cell *> > >

我猜这是迭代器操作没有被内联并导致这种巨大的差异。有什么办法可以改善这一点吗?只要仍然可以在源代码中逐行检查并检查所有变量值,我就可以在发布模式下进行调试。

4

4 回答 4

3

差异是正常的。我会做的是地方

#pragma optimize("",off)

#pragma optimize("",on)

围绕您要检查的方法,并将构建的其余部分保持在发布模式。

于 2012-08-25T06:52:30.543 回答
2

6 分钟与 20 秒的比例为 18:1(为简单起见,将其称为 20:1)。

这意味着调试版本花费了 95% 的时间来做一些发布版本没有的额外事情。

OK,在调试器下运行。点击暂停按钮并查看调用堆栈。您将有 19/20 的机会看到花费了额外时间的原因。做几次以确定。

当我这样做时,它正在执行类验证方法,这些方法在发布模式下被关闭。通常它是通过不同的路径一遍又一遍地重新验证相同的数据。

在您的情况下,很可能是那些迭代器。如果您不做太多其他事情,他们很容易成为主导者。

但不要猜测。

于 2012-08-25T12:56:49.233 回答
2

一个问题是,在 VC++ 调试版本中默认启用的“快速调试检查”将使您的代码速度降低多达五倍。他们偶尔会发现错误,但不足以证明您所看到的成本是合理的。有关详细信息,请参阅我的博客文章:

Visual C++ 调试构建——“快速检查”导致 5 倍减速

关闭它们,每个小功能都会明显加快。

于 2012-10-10T23:16:14.980 回答
1

如果您的减速仅在于调试器内部的初始化(但如果您将 Debug 构建作为常规应用程序运行则不会),这是由 Visual Studio 为您正在使用的所有库加载调试符号引起的。这是意料之中的,但您可以微调从调试首选项中加载哪些符号。

一般来说,缺乏优化当然会减慢速度,但不会特别是在调试器内部启动时。

于 2012-08-25T08:24:30.230 回答