Почему 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% процессорного времени.

  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 (описанным ниже), которое является числом в секунду значения, возвращаемого функцией 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 не было времени ожидания.)

Другие вопросы по тегам