Я пытался измерить время для фрагмента кода и заметил, что время было примерно на 50 нс быстрее, когда я запускал программу из своего редактора QtCreator, по сравнению с тем, когда я запускал ее из оболочки bash, запущенной в gnome-терминал. Я использую Ubuntu 20.04 в качестве ОС.
Небольшая программа для воспроизведения моей проблемы:
#include <stdio.h>
#include <time.h>
struct timespec now() {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return now;
}
long interval_ns(struct timespec tick, struct timespec tock) {
return (tock.tv_sec - tick.tv_sec) * 1000000000L
+ (tock.tv_nsec - tick.tv_nsec);
}
int main() {
// sleep(1);
for (size_t i = 0; i < 10; i++) {
struct timespec tick = now();
struct timespec tock = now();
long elapsed = interval_ns(tick, tock);
printf("It took %lu ns\n", elapsed);
}
return 0;
}
Вывод при запуске из QtCreator
It took 84 ns
It took 20 ns
It took 20 ns
It took 21 ns
It took 21 ns
It took 21 ns
It took 22 ns
It took 21 ns
It took 20 ns
It took 21 ns
И при запуске из моей оболочки внутри терминала:
$ ./foo
It took 407 ns
It took 136 ns
It took 74 ns
It took 73 ns
It took 77 ns
It took 79 ns
It took 74 ns
It took 81 ns
It took 74 ns
It took 78 ns
Вещи, которые я пробовал, которые не имели значения
- Разрешение QtCreator запускать программу в терминале
- Использование вызовов rdtsc и rdtscp вместо clock_gettime (те же относительные различия во время выполнения)
- очистка окружения из терминала, запустив его под
env -i
- Запуск программы с использованием sh вместо bash
Я проверил, что один и тот же двоичный файл вызывается во всех случаях. Я убедился, что значение nice равно 0 для программы во всех случаях.
Вопрос
Почему запуск программы из моей оболочки имеет значение? Любые предложения о том, что попробовать?
Обновлять
Если я добавлю вызов sleep(1) в начало main, вызовы QtCreator и gnome-terminal/bash сообщат о более длительном времени выполнения.
Если я добавлю вызов system(ps -H) в начале main, но уберу ранее упомянутый sleep(1): оба вызова сообщают о коротком времени выполнения (~ 20 нс).
long
является 32-битным, код легко переполняется. Предложитьlong long interval_ns(struct timespec tick, struct timespec tock) { return (tock.tv_sec - tick.tv_sec) * 1000000000LL + (tock.tv_nsec - tick.tv_nsec); }
(изменить тип и LL) - person chux - Reinstate Monica   schedule 04.08.2020