Измерение времени выполнения выбранных циклов

Я хочу измерить время выполнения выбранных циклов в программе C, чтобы увидеть, какой процент от общего времени выполнения программы (в Linux) тратится на эти циклы. Я должен иметь возможность указать циклы, для которых должна быть измерена производительность. Я опробовал несколько инструментов (vtune, hpctoolkit, oprofile) за последние несколько дней, и ни один из них, похоже, не делает этого. Все они находят узкие места в производительности и просто показывают время для них. Это потому, что эти инструменты сохраняют только затраченное время, превышающее пороговое значение (~ 1 мс). Поэтому, если один цикл занимает меньше времени, чем это, то время его выполнения не будет сообщено.

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

Я мог бы вручную написать простой таймер, используя gettimeofday или что-то в этом роде, но в некоторых случаях это не даст точных результатов. Например:

for (i = 0; i < 1000; ++i)
{
    for (j  = 0; j < N; ++j)
    {
        //do some work here
    }
}

Теперь я хочу измерить общее время, проведенное во внутреннем цикле, и мне нужно будет поместить вызов gettimeofday в первый цикл. Таким образом, сам gettimeofday будет вызываться 1000 раз, что вносит свои собственные накладные расходы, и результат будет неточным.


person Arjun Singri    schedule 29.04.2010    source источник
comment
Очень часто люди спрашивают, как измерить время, когда на самом деле они хотят знать, как уменьшить время. Это то, что вам нужно?   -  person Mike Dunlavey    schedule 30.04.2010
comment
Неа. Я просто хочу измерить время. Я характеризую циклы в программе на основе нескольких шаблонов и хочу знать время их выполнения относительно времени выполнения всей программы.   -  person Arjun Singri    schedule 30.04.2010


Ответы (3)


Если у вас нет встроенного эмулятора или коммутационной коробки вокруг вашего ЦП, нет такой вещи, как синхронизация одного цикла или одной инструкции. Вам нужно увеличить количество тестовых прогонов до чего-то, что занимает не менее нескольких секунд каждый, чтобы уменьшить количество ошибок из-за других вещей, происходящих в ЦП, ОС и т. д.

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

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

Это верно независимо от того, измеряете ли вы производительность с помощью счетчиков высокой производительности менее миллисекунды, предоставляемых ЦП, системных часов даты и времени или настенных часов для измерения прошедшего времени вашего теста.

В противном случае вы просто измеряете белый шум.

person dthorpe    schedule 29.04.2010

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

Любые инструкции по профилированию несут свои собственные накладные расходы, но, по-видимому, накладные расходы будут одинаковыми независимо от того, где они вставлены, поэтому «все выходит в стирку». Предположительно, вы ищете места, где есть значительные различия между временем выполнения двух сравниваемых процессов, где пара вызовов функций, подобных этому, не будет проблемой (поскольку вам нужен еще один в «конце», чтобы получить время дельта), так как одна процедура будет в 2 раза или более дорогостоящей по сравнению с другой.

Большинство платформ также предлагают таймер с более высоким разрешением, хотя тот, который мы используем здесь, скрыт за API, поэтому «клиентский» код является кросс-платформенным. Я уверен, что немного посмотрев, вы сможете поднять его. Хотя даже здесь маловероятно, что вы получите точность выше 1 мс, поэтому предпочтительнее запускать код несколько раз подряд и измерять время всего выполнения (затем разделить на количество циклов, естественно).

person dash-tom-bang    schedule 29.04.2010