РЕДАКТИРОВАТЬ: Я только что нашел свою проблему после написания этого длинного поста, объясняющего каждую мелочь ... Если кто-то может дать мне хороший ответ о том, что я делаю неправильно, и как я могу получить исполнение время в секундах (используя число с 5 десятичными знаками или около того), я отмечу это как принятое. Подсказка: проблема заключалась в том, как я интерпретировал справочную страницу clock_getttime ().
Привет
Допустим, у меня есть функция с именем myOperation
, для которой мне нужно измерить время выполнения. Чтобы измерить это, я использую clock_gettime()
, как это было рекомендовано здесь в одном из комментариев.
Мой учитель рекомендует нам измерить его N
раз, чтобы мы могли получить среднее, стандартное отклонение и медиану для окончательного отчета. Он также рекомендует нам выполнить myOperation
M
раз вместо одного. Если myOperation
- очень быстрая операция, то ее измерение M
раз позволит нам получить представление о «реальном времени», которое требуется; потому что используемые часы могут не иметь необходимой точности для измерения такой операции. Таким образом, выполнение myOperation
только один раз или M
раз действительно зависит, если сама операция занимает достаточно много времени для точности используемых нами часов.
У меня проблемы с этим M
казнью. Увеличение M
уменьшает (много) окончательное среднее значение. Что не имеет смысла для меня. Примерно так: в среднем у вас уходит от 3 до 5 секунд, чтобы добраться из точки А в В. Но затем вы переходите от А к В и обратно к А 5 раз (что составляет 10 раз, потому что от А до Б - то же самое, что и В). а) и вы измеряете это. Если вы разделите на 10, то среднее значение, которое вы получите, должно быть таким же, как и среднее, которое вы берете, путешествуя из пункта А в пункт Б, то есть от 3 до 5 секунд.
Это то, что я хочу, чтобы мой код делал, но он не работает. Если я продолжу увеличивать количество раз, когда я иду от А к В и обратно А, среднее будет с каждым разом все меньше и меньше, для меня это не имеет смысла.
Достаточно теории, вот мой код:
#include <stdio.h>
#include <time.h>
#define MEASUREMENTS 1
#define OPERATIONS 1
typedef struct timespec TimeClock;
TimeClock diffTimeClock(TimeClock start, TimeClock end) {
TimeClock aux;
if((end.tv_nsec - start.tv_nsec) < 0) {
aux.tv_sec = end.tv_sec - start.tv_sec - 1;
aux.tv_nsec = 1E9 + end.tv_nsec - start.tv_nsec;
} else {
aux.tv_sec = end.tv_sec - start.tv_sec;
aux.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return aux;
}
int main(void) {
TimeClock sTime, eTime, dTime;
int i, j;
for(i = 0; i < MEASUREMENTS; i++) {
printf(" » MEASURE %02d\n", i+1);
clock_gettime(CLOCK_REALTIME, &sTime);
for(j = 0; j < OPERATIONS; j++) {
myOperation();
}
clock_gettime(CLOCK_REALTIME, &eTime);
dTime = diffTimeClock(sTime, eTime);
printf(" - NSEC (TOTAL): %ld\n", dTime.tv_nsec);
printf(" - NSEC (OP): %ld\n\n", dTime.tv_nsec / OPERATIONS);
}
return 0;
}
Примечания: Вышеупомянутая diffTimeClock
функция взята из этого сообщения в блоге . Я заменил свою реальную операцию на myOperation()
, потому что публиковать мои реальные функции не имеет никакого смысла, так как мне пришлось бы публиковать длинные блоки кода, вы можете легко кодировать myOperation()
с любым, что вам нравится для компиляции кода, если Вы хотите.
Как видите, OPERATIONS = 1
и результаты:
» MEASURE 01
- NSEC (TOTAL): 27456580
- NSEC (OP): 27456580
Для OPERATIONS = 100
результаты:
» MEASURE 01
- NSEC (TOTAL): 218929736
- NSEC (OP): 2189297
Для OPERATIONS = 1000
результаты:
» MEASURE 01
- NSEC (TOTAL): 862834890
- NSEC (OP): 862834
Для OPERATIONS = 10000
результаты:
» MEASURE 01
- NSEC (TOTAL): 574133641
- NSEC (OP): 57413
Так вот, я не математик, на самом деле это далеко не так, но для меня это не имеет никакого смысла. Я уже говорил об этом с другом, который участвует в этом проекте со мной, и он также не может понять различия. Я не понимаю, почему значение становится все меньше и меньше при увеличении OPERATIONS
. Сама операция должна занимать одно и то же время (в среднем, конечно, не одно и то же), независимо от того, сколько раз я ее выполняю.
Вы могли бы сказать мне, что это на самом деле зависит от самой операции, читаемых данных и что некоторые данные уже могут быть в кеше и т. Д., Но я не думаю, что это проблема. В моем случае myOperation
читает 5000 строк текста из файла CSV, разделяя значения на ;
и вставляя эти значения в структуру данных. Для каждой итерации я уничтожаю структуру данных и заново ее инициализирую.
Теперь, когда я думаю об этом, я также думаю, что есть проблема измерения времени с clock_gettime()
, возможно, я не правильно его использую. Я имею в виду, посмотрите на последний пример, где OPERATIONS = 10000
. Общее время, которое потребовалось, составило 574133641 нс, что составляет примерно 0,5 с; это невозможно, это заняло пару минут, так как я не мог стоять и смотреть на экран в ожидании и пошел что-то есть.