Почему CLOCKS_PER_SEC не является фактическим числом часов в секунду?

Я только что написал эту короткую программу на C ++, чтобы приблизиться к фактическому количеству тактов в секунду.

#include  #include  using namespace std; int main () { for(int i = 0; i < 10 ; i++) { int first_clock = clock(); int first_time = time(NULL); while(time(NULL) <= first_time) {} int second_time = time(NULL); int second_clock = clock(); cout << "Actual clocks per second = " << (second_clock - first_clock)/(second_time - first_time) << "\n"; cout << "CLOCKS_PER_SEC = " << CLOCKS_PER_SEC << "\n"; } return 0; } 

Когда я запускаю программу, я получаю вывод, который выглядит так.

 Actual clocks per second = 199139 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 638164 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 610735 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 614835 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 642327 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 562068 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 605767 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 619543 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 650243 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 639128 CLOCKS_PER_SEC = 1000000 

Почему фактическое количество тактов в секунду не совпадает с CLOCKS_PER_SEC? Они даже не равны. Что тут происходит?

clock возвращает количество времени, затраченного в вашей программе. Всего 1 000 000 тактов в секунду * . Похоже, что ваша программа потребляла 60% из них.

Что-то еще использовало другие 40%.

* Хорошо, в секунду есть около 1 000 000 тактов. Фактическое число нормализуется, поэтому ваша программа воспринимает 1 000 000 тиков.

На странице руководства clock(3) :

POSIX требует, чтобы CLOCKS_PER_SEC равнялся 1000000 независимо от фактического разрешения.

По-видимому, ваша реализация, по-видимому, соответствует POSIX.

Запустив вашу программу здесь, я получаю

 Actual clocks per second = 980000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 1000000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 990000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 1000000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 1000000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 1000000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 1000000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 1000000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 1000000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 1000000 CLOCKS_PER_SEC = 1000000 

или аналогичный вывод на холостом компьютере, и вывод

 Actual clocks per second = 50000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 600000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 530000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 580000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 730000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 730000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 600000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 560000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 600000 CLOCKS_PER_SEC = 1000000 Actual clocks per second = 620000 CLOCKS_PER_SEC = 1000000 

на занятой машине. Поскольку clock() измеряет (приблизительное) время, проведенное в вашей программе, кажется, что вы тестировали на занятой машине, и ваша программа получила только около 60% времени процессора.

  1. CLOCKS_PER_SECOND в POSIX – постоянная, равная 1000000.
  2. CLOCKS_PER_SECOND не должен показывать количество часов в вашем процессе. Это номер разрешения, который вы можете использовать для преобразования количества часов в количество времени (см. Справочную страницу для функции clock ()).

Например, если вы вычислите:

(Second_clock-first_clock) / CLOCKS_PER_SEC

вы получите общее время между первым и вторым вызовом функции «clock ()».

Стандарт C99

Единственное, о чем говорит стандартный проект C99 N1256 о CLOCKS_PER_SEC заключается в следующем:

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

Как отмечают другие, POSIX устанавливает его в 1 миллион, что ограничивает точность этого до 1 микросекунды. Я думаю, что это всего лишь историческое значение с тех дней, когда максимальные частоты процессора измерялись в Mega Hertz.

Хорошо, дух. Вы не знаете, как далеко в текущую секунду вы начинаете отсчет времени, не так ли? Таким образом, вы можете получить любой результат от 1 до CLOCKS_PER_SEC. Попробуйте это в своем внутреннем цикле:

 int first_time = time(NULL); // Wait for timer to roll over before starting clock! while(time(NULL) <= first_time) {} int first_clock = clock(); first_time = time(NULL); while(time(NULL) <= first_time) {} int second_time = time(NULL); int second_clock = clock(); cout << "Actual clocks per second = " << (second_clock - first_clock)/(second_time - first_time) << "\n"; cout << "CLOCKS_PER_SEC = " << CLOCKS_PER_SEC << "\n"; 

См. Ideone для полного исходного кода. Он сообщает фактические часы в секунду как 1000000, как и следовало ожидать. (Мне пришлось сократить количество итераций до 2, так что идеон не уходил.)

Давайте будем гением компьютера.