Есть ли лучший способ для сравнения программ на C, чем время? - PullRequest
12 голосов
/ 17 сентября 2011

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

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

Мой вопрос:

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

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

Заранее спасибо за любой вклад!

Результаты:

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

Ответы [ 5 ]

11 голосов
/ 17 сентября 2011

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

3 голосов
/ 17 сентября 2011

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

2 голосов
/ 17 сентября 2011

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

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

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

1 голос
/ 17 сентября 2011

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

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

1 голос
/ 17 сентября 2011

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

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

...