Как измерить ACTUAL время выполнения программы C под Linux?

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

Я использовал getrusage(), чтобы получить время пользователя и системное время процесса, а затем вычислить фактическое время выполнения (пользовательское время + системное время). Я запускаю свою программу на Ubuntu. Вот мои вопросы:

  • Как узнать точность getrusage()?
  • Существуют ли другие подходы, которые могут обеспечить более высокую точность, чем getrusage()?

Ответ 1

Вы можете проверить реальное время процессора процесса в Linux, используя CPU Time в ядре:

 #include <time.h>

 clock_t start, end;
 double cpu_time_used;

 start = clock();
 ... /* Do the work. */
 end = clock();
 cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

Источник: http://www.gnu.org/s/hello/manual/libc/CPU-Time.html#CPU-Time

Таким образом, вы считаете тики процессора или реальный объем инструкций, выполняемых процессором в процессе, тем самым получая реальный объем рабочего времени.

Ответ 2

Функция getrusage() является единственным стандартным/переносным способом, который, как я знаю, "потребляет процессорное время".

Нет простого способа определить точность возвращаемых значений. У меня возникнет соблазн вызвать getrusage() один раз, чтобы получить начальное значение, и вызвать его несколько раз, пока возвращаемые значения /s не будут отличаться от начального значения, а затем предположим, что эффективная точность - это разница между начальным и конечным значения. Это взлом (было бы возможно, чтобы точность была выше, чем этот метод определяет, и результат, вероятно, следует считать наихудшей оценкой), но это лучше, чем ничего.

Я также буду беспокоиться о точности возвращаемых значений. В некоторых ядрах я ожидаю, что счетчик будет увеличен, если какой-либо код будет запущен, когда произойдет IRQ таймера; и поэтому для процесса может быть очень повезло (и он постоянно блокируется непосредственно перед таймером таймера) или очень неудачно (и разблокируется непосредственно перед тем, как происходит IRQ таймера). В этом случае "удачливый" может означать, что процессорный свиньи выглядит так, будто он не использует процессорное время, а "неудачный" может означать, что процесс, который использует очень мало процессорного времени, похож на CPU hog.

Для конкретных версий конкретных ядер по определенной архитектуре /s (потенциально в зависимости от того, когда/когда ядро ​​скомпилировано с определенными параметрами конфигурации в некоторых случаях), могут быть более высокие прецизионные альтернативы, которые не являются переносимыми и не являются стандартными...

Ответ 3

Вы можете использовать этот фрагмент кода:

#include <sys/time.h>
struct timeval start, end;
gettimeofday(&start, NULL);
.
.
.
gettimeofday(&end, NULL);
delta = ((end.tv_sec  - start.tv_sec) * 1000000u +
         end.tv_usec - start.tv_usec) / 1.e6;
printf("Time is : %f\n",delta);

Покажет вам время выполнения фрагмента кода