Почему CLOCKS_PER_SEC не является фактическим числом часов в секунду?
Я только что написал эту короткую программу на С++, чтобы приблизить фактическое количество тактов в секунду.
#include <iostream>
#include <time.h>
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? Они даже не равны. Что здесь происходит?
Ответы
Ответ 1
clock
возвращает время, затрачиваемое в вашей программе. Есть 1 000 000 тактов в секунду в секунду *. Похоже, что ваша программа потребляла 60% из них.
Что-то еще использовало другие 40%.
* Хорошо, в секунду есть почти 1 000 000 тактов. Фактическое число нормализуется, поэтому ваша программа воспринимает 1 000 000 тиков.
Ответ 2
На странице руководства 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% времени процессора.
Ответ 3
- CLOCKS_PER_SECOND в POSIX - это константа, равная 1000000.
- CLOCKS_PER_SECOND не должен показывать количество часов в вашем процессе. Это номер разрешения, который вы можете использовать для преобразования количества часов в количество времени. (См. Страницу man для функции clock())
Например, если вы вычислите:
(second_clock-first_clock)/CLOCKS_PER_SEC
вы получите общее время между первым и вторым вызовами функции "clock()".
Ответ 4
Стандарт C99
Единственное, что C99 N1256 standard draft говорит о CLOCKS_PER_SEC
, заключается в следующем:
CLOCKS_PER_SEC который расширяется до выражения с типом clock_t (описанным ниже), которое является число в секунду значения, возвращаемого функцией часов
Как отмечают другие, POSIX устанавливает его в 1 миллион, что ограничивает точность этого до 1 микросекунды. Я думаю, что это просто историческое значение с тех дней, когда максимальные частоты процессора измерялись в мегагерце.
Ответ 5
Ну, дух. Вы не знаете, как далеко в текущую секунду вы начинаете отсчет времени, не так ли? Таким образом, вы можете получить любой результат от 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, так что идеон не уходил.)