Как измерить время выполнения фрагмента кода?
Предположим, я хочу измерить время, которое занимает определенный фрагмент кода. Для этого я бы обычно делал что-то подобное
clock_t startTime = clock();
//do stuff
//do stuff
//do stuff
//do stuff
float secsElapsed = (float)(clock() - startTime)/CLOCKS_PER_SEC;
Что если программа многопоточная и контекстные переключения происходят внутри части, которую я хочу измерить? Как бы я измерил время, необходимое для выполнения моего кода, исключая время, потраченное на другие потоки? Даже если есть инструменты, которые это делают, мне бы очень хотелось узнать, как они это делают.
4 ответа
Есть разные способы измерить, сколько времени занимает выполнение кода.
Если вас интересует относительная производительность определенных функций, профилировщик - единственный путь. Обратите внимание, что это ослабит влияние блокировки ввода-вывода из-за накладных расходов, которые он вызывает.
Если вам нужно время определенных функций, основанное на часах, есть множество вариантов.
Лично я бы сказал, что gettimeofday достаточно.
Если вы хотите получить точную информацию, используйте RDTSC
Если вы хотите быть очень точным, вам нужно что-то вроде этого
t1 = rdtsc();
t2 = rdtsc();
my_code();
t3 = rdtsc();
my_code_time = (t3-t2) - (t2-t1)
Вам нужно будет повторить этот блок, чтобы учесть несоответствия в планировании потоков, а также обратить внимание на эффекты кэширования.
Вот почему бенчмаркинг кода в основном отстой - потому что вы не можете знать, сколько времени это займет. Такие вещи, как упреждение ОС, в лучшем случае непредсказуемы. Используйте профессиональный профилировщик, так как они могут иметь код, который может решить эти проблемы, или не беспокоиться. Пишу clock()
Стиль вещей совершенно бессмыслен.
Из терминала Linux используйте 'time path_to_app'
Это вернет все, что вы хотите знать.
Я подготовил два очень простых занятия. Первый ProfileHelper класс заполняет время начала в конструкторе и время окончания в деструкторе. Второй класс ProfileHelperStatistic - это контейнер с дополнительной статистической возможностью (std::multimap + несколько методов для возврата среднего, стандартного отклонения и других забавных вещей).
Я часто использовал эту идею для профилирования. Я думаю, вы могли бы заставить его работать даже в многопоточной среде. Это потребует немного работы, но я не думаю, что это будет так сложно.
Посмотрите на этот вопрос для получения дополнительной информации C++ Benchmark tool.