Как измерить 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);
Покажет вам время выполнения фрагмента кода