Есть ли лучший способ сравнить программу C, чем время?

Я кодирую небольшую программу, которая должна сортировать большой массив (до 4 миллионов текстовых строк). Похоже, я неплохо справляюсь с этим, поскольку комбинация radixsort и mergesort уже сократила время выполнения сортировки оригинала q (uick) менее чем наполовину.

Время выполнения является основным моментом, так как это то, что я использую для сравнения моей части кода.

Мой вопрос:

Есть ли лучший (более надежный) способ бенчмаркинга программы, чем просто время исполнения? Это работает, но одна и та же программа (с теми же фоновыми процессами) обычно имеет несколько другое время выполнения, если выполняется дважды.

Этот вид поражает цель обнаружения небольших улучшений. И несколько небольших улучшений могут добавить к большому...

Заранее благодарим за любой ввод!

Результаты:

Мне удалось заставить gprof работать под Windows (используя gcc и MinGW). gcc ведет себя плохо (учитывая время выполнения) по сравнению с моим обычным компилятором (tcc), но это дало мне довольно глубокое понимание.

Ответ 1

Попробуйте инструмент профилирования, который также покажет вам, где программа тратит свое время. gprof - это классический инструмент профилирования C, по крайней мере, в Unix.

Ответ 2

Посмотрите на команду time. Он отслеживает как время процессора, так и время настенных часов. Вы также можете использовать что-то вроде gprof для профилирования кода, чтобы найти части вашей программы, которые на самом деле занимают больше всего времени. Вы можете сделать более низкотехнологичную версию профилирования с помощью таймеров в вашем коде. Boost имеет класс timer, но легко свернуть свои собственные.

Ответ 3

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

По существу вам нужно принять измерения N, отбросить выбросы и рассчитать среднее время работы среднего и среднего и стандартного отклонения с измерением неопределенности.

Вот хороший блог, объясняющий, почему и как это сделать (с кодом): http://blogs.perl.org/users/steffen_mueller/2010/09/your-benchmarks-suck.html

Ответ 4

Что вы используете для синхронизации времени? Там C89 clock() в time.h для стартеров. В unixoid системах вы можете найти getitimer() для ITIMER_VIRTUAL для измерения времени процессора. Подробнее см. В соответствующих страницах руководства.

Вы также можете использовать служебную программу pOSIX shell times для тестирования времени процессора, используемого процессом и его дочерними элементами. Разрешение зависит от системы, как и все, что связано с профилированием. Попробуйте обернуть свой код C в цикле, выполнив его столько раз, сколько необходимо, чтобы уменьшить "дрожание" во время отчетов о контрольных показателях.

Ответ 5

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

Если вы работаете в Linux или аналогично, вы также можете использовать taskset для привязки кода к определенному ядру ЦП (при условии, что он имеет однопоточность), в идеале - не ядро ​​0, поскольку это имеет тенденцию обрабатывать все прерывания.