Проблема VC6 Profiler: ложные вызовы функций

Я столкнулся со следующей проблемой при профилировании приложения в VC6. Когда я профилирую приложение, профилировщик указывает, что простой метод получения, подобный следующему, вызывается много сотен тысяч раз:

int SomeClass::getId() const
{
   return m_iId;
};

Проблема в том, что этот метод нигде не вызывается в тестовом приложении. Когда я меняю код на следующий:

int SomeClass::getId() const
{
   std::cout << "Is this method REALLY being called?" << std::endl;
   return m_iId;
};

Профилировщик никогда не включает getId в список вызываемых функций. Закомментируйте cout, и я вернусь к тому, с чего начал, 130+ тысяч звонков! Просто чтобы убедиться, что это не какие-то кешированные данные профилировщика или поврежденная таблица поиска функций, я выполняю очистку и перестройку между каждым тестом. Все те же результаты!

Любые идеи?


person acanaday    schedule 02.07.2010    source источник


Ответы (2)


Я предполагаю, что происходит то, что компилятор и/или компоновщик «объединяют» эту очень простую функцию с одной или несколькими другими функциями, которые идентичны (код, сгенерированный для return m_iId, вероятно, точно такой же, как и многие другие геттеры, которые происходят чтобы вернуть элемент с тем же смещением).

по сути, набор различных функций, которые имеют идентичные реализации машинного кода, разрешаются по одному и тому же адресу, что сбивает с толку профилировщика.

Вы можете предотвратить это (если это проблема), отключив оптимизацию.

person Michael Burr    schedule 02.07.2010
comment
Знаете, я думаю, что это может быть причиной моей проблемы. Я предположил, что проблема была в файле карты, когда исчезла некоторая странная информация о профилировании, но я только что заметил, что появлялись некоторые другие геттеры, которые не вызывались напрямую. Отключив оптимизацию, я получаю правильные имена. - person acanaday; 02.07.2010
comment
Мне было интересно, почему профилировщик VC6 использует файл карты, а не pdb, но я так давно не использовал его, что подумал, что, может быть, это было тогда. - person Michael Burr; 02.07.2010

Я предполагаю, что вы профилируете, потому что хотите узнать, есть ли способы сократить время работы программы, верно? Вы не просто профилируете, потому что вам нравится видеть цифры.

Есть простой, старомодный, проверенный способ найти проблемы с производительностью. Во время работы программы просто нажмите кнопку «пауза» и посмотрите на стек вызовов. Сделайте это несколько раз, например, от 5 до 20 раз. Чем больше проблема, тем меньше образцов вам нужно, чтобы найти ее.

Некоторые спрашивают, не этим ли в основном занимаются профилировщики, и отвечают, что очень немногие. Большинство профилировщиков поддаются одному или нескольким распространенным мифам, в результате чего ваше ускорение ограничено потому что они не находят все проблемы:

  • Некоторые программы проводят ненужное время в «горячих точках». В этом случае вы увидите, что код в «конце» стека (где находится программный счетчик) выполняет ненужную работу.

  • Некоторые программы выполняют больше операций ввода-вывода, чем необходимо. Если это так, вы увидите, что они находятся в процессе выполнения этого ввода-вывода.

  • Большие программы часто работают медленно, потому что их деревья вызовов излишне густы и нуждаются в обрезке. Если это так, вы увидите ненужные вызовы функций в середине стека.

Любой код, который вы видите в некотором проценте стеков, если его удалить, сэкономит этот процент времени выполнения (более или менее). Вы не ошибетесь. Вот пример сохранения более 97 %.

person Mike Dunlavey    schedule 02.07.2010