Почему CLOCKS_PER_SEC не фактическое количество часов в секунду?
Я только что написал эту короткую программу на C++, чтобы приблизить фактическое количество тактов в секунду.
#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? Они даже не примерно равны. Что тут происходит?
5 ответов
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% процессорного времени.
- CLOCKS_PER_SECOND в POSIX - это константа, равная 1000000.
- CLOCKS_PER_SECOND не должен показывать количество часов в вашем процессе. Это число разрешения, которое вы можете использовать для преобразования количества часов в количество времени (см. Справочную страницу для функции clock()).
Например, если вы рассчитываете:
(Second_clock-first_clock)/CLOCKS_PER_SEC
Вы получите общее время между первым и вторым вызовом функции "clock()".
Стандарт C99
Единственное, о чем говорит стандартный проект C99 N1256, CLOCKS_PER_SEC
в том, что:
CLOCKS_PER_SEC, которая расширяется до выражения с типом clock_t (описанным ниже), которое является числом в секунду значения, возвращаемого функцией clock
Как упоминают другие, POSIX устанавливает его на 1 миллион, что ограничивает точность до 1 микросекунды. Я думаю, что это просто историческое значение из тех дней, когда максимальные частоты процессора измерялись в мегагерцах.
Когда вы устанавливаете int first_time = time(NULL); время (NULL) может быть "на расстоянии 1 наносекунды" (потому что оно усечено) до поворота +1. Следовательно ,: while (time (NULL) <= first_time) {} можно перепрыгнуть быстрее, чем на 1 секунду, быстрее, чем вы ожидали.
Вот почему в вашей "1 секунде" меньше часов.
Ну да. Вы не знаете, как далеко в текущую секунду вы начинаете отсчет времени? Таким образом, вы можете получить любой результат от 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, чтобы у ideone не было времени ожидания.)