Подтвердить что ты не робот

Почему 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? Они даже не равны. Что здесь происходит?

4b9b3361

Ответ 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, так что идеон не уходил.)