Проблема профилировщика VC6: ложные вызовы функций
Я сталкиваюсь с следующей проблемой при профилировании приложения под 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 тысяч звонков! Просто чтобы убедиться, что это не какие-то кэшированные данные профилировщика или таблица поиска поврежденных функций, я делаю чистку и перестройку между каждым тестом. Все те же результаты!
Есть идеи?
2 ответа
Я предполагаю, что происходит то, что компилятор и / или компоновщик "объединяют" эту очень простую функцию с одной или несколькими другими функциями, которые идентичны (код, сгенерированный для return m_iId
скорее всего, точно так же, как и многие другие получатели, которые возвращают члена с таким же смещением).
по существу, множество различных функций, которые имеют одинаковые реализации машинного кода, все разрешаются по одному адресу, что приводит в замешательство профилировщик.
Вы можете остановить это (если это проблема), отключив оптимизацию.
Я предполагаю, что вы профилируете, потому что вы хотите узнать, есть ли способы заставить программу занимать меньше времени, верно? Вы не просто профилируете, потому что вам нравится видеть цифры.
Существует простой, старомодный, проверенный способ найти проблемы с производительностью. Пока программа работает, просто нажмите кнопку "пауза" и посмотрите на стек вызовов. Сделайте это несколько раз, например, от 5 до 20 раз. Чем больше проблема, тем меньше образцов вам нужно найти.
Некоторые люди спрашивают, не является ли это в основном тем, что делают профилировщики, и ответ только очень немного. Большинство профилировщиков относятся к одному или нескольким распространенным мифам, в результате чего ваше ускорение ограничено, потому что они не находят все проблемы:
Некоторые программы проводят ненужное время в "горячих точках". Когда это так, вы увидите, что код на "конце" стека (где находится счетчик программ) выполняет ненужную работу.
Некоторые программы выполняют больше операций ввода-вывода, чем необходимо. Если это так, вы увидите, что они находятся в процессе ввода / вывода.
Большие программы часто работают медленно, потому что их деревья вызовов неоправданно густы и требуют обрезки. Если это так, вы увидите ненужные вызовы функций в середине стека.
Любой код, который вы видите в некотором проценте стеков, в случае удаления сохранит этот процент времени выполнения (более или менее). Вы не можете пойти не так. Вот пример, за несколько итераций, экономия более 97%.