почему C clock () возвращает 0 - PullRequest
8 голосов
/ 26 марта 2012

У меня есть что-то вроде этого:

clock_t start, end;
start=clock();

something_else();

end=clock();
printf("\nClock cycles are: %d - %d\n",start,end);

, и я всегда получаю в качестве вывода «Тактовые циклы: 0 - 0»

Есть идеи, почему это происходит?

(Просто чтобы дать немного подробностей, функция some_else () выполняет возведение влево-вправо, используя представление montgomery, более того, я не знаю наверняка, что функцияthing_else () действительно занимает некоторое время, которое нельзя пренебречь.)

Это на Linux.Результат uname -a:

Linux snowy.*****.ac.uk 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux

Ответы [ 6 ]

7 голосов
/ 26 марта 2012

clock функция не измеряет тактовые частоты процессора.

C говорит: clock "возвращает наилучшее приближение реализации к процессору время, используемое программой с начала определенной эпохой реализации, связанной с только для вызова программы. "

Если между двумя последовательными вызовами clock ваша программа занимает меньше времени, чем одно целое функции clock, вы можете получить 0.

POSIX clock определяет единство с CLOCKS_PER_SEC как 1000000 (тогда единица равна 1 микросекунде).

http://pubs.opengroup.org/onlinepubs/009604499/functions/clock.html

Для измерения тактовых циклов в x86 / x64 вы можете использовать встроенную сборку, чтобы получить счетчик тактов регистра счетчика меток времени CPU rdtsc.

6 голосов
/ 26 марта 2012

Я думаю, причина в том, что ваш something_else() потребляет так мало времени, что превышает точность clock(). Я пытался дважды вызывать clock(), и оба значения start и end равны нулю, но результат разумный, когда я занимаюсь чем-то трудоемким между.

Вот мой фрагмент кода теста:

int main(void) {   
    clock_t start, end;
    start = clock();
    int c;
    for (int i = 0; i < 100; i++) {
        for (int j = 0; j < (1<<30); j++) {
            c++;
        }
    }
    end = clock();
    printf("start = %d, end = %d\n", start, end);
    return 0;
}

И результат на моем компьютере:

start = 0, end = 27700000

Кроме того, два совета:

  1. При тестировании не использовать оптимизацию компилятора . Вы можете подумать, что ваш something_else() отнимает много времени, но компилятор может просто игнорировать эти операции (особенно циклы), так как считает их бессмысленными.
  2. Используйте sizeof(clock_t) на своей платформе, чтобы увидеть размер clock_t.
5 голосов
/ 26 марта 2012

Ну, вы хотите, чтобы время something_else() заняло?Попробуйте это:

#include <sys/time.h>
#include <stdio.h>  
#include <unistd.h>
int main(void) {
    struct timeval start, end;
    long mtime, secs, usecs;    

    gettimeofday(&start, NULL);
    something_else();
    gettimeofday(&end, NULL);
    secs  = end.tv_sec  - start.tv_sec;
    usecs = end.tv_usec - start.tv_usec;
    mtime = ((secs) * 1000 + usecs/1000.0) + 0.5;
    printf("Elapsed time: %ld millisecs\n", mtime);
    return 0;
}
2 голосов
/ 26 марта 2012

Правильный способ использования clock () для измерения времени:

printf("\nTime elapsed: %.2f\n",1.0*(end-start)/CLOCKS_PER_SEC);

Это потому, что clock_t не гарантированно будет int или любым другим типом в этом отношении.

2 голосов
/ 26 марта 2012

Проверьте значение CLOCKS_PER_SEC в time.h/clock.h.Например, в моей системе (Dev Cpp на Windows 7) это просто 1000.Так что, что касается моей программы, то есть 1000 тиков в секунду.Ваш something_else будет выполнен за считанные микросекунды.И, следовательно, clock() возвращает ноль как до, так и после вызова функции.

В моей системе, когда я заменяю ваш something_else на такую ​​трудоемкую процедуру, как это

for (unsigned i=0xFFFFFFFF;i--;);

start=clock();

for (unsigned i=0xFFFFFFFF;i--;);

end=clock();

Тактовые циклы: 10236 - 20593

В одной из коробок Linux я нахожу следующее в bits/time.h

/* ISO/IEC 9899:1990 7.12.1: <time.h>
   The macro `CLOCKS_PER_SEC' is the number per second of the value
   returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
   The value of CLOCKS_PER_SEC is required to be 1 million on all
   XSI-conformant systems. */
#  define CLOCKS_PER_SEC  1000000l

учитывайте это перед анализом возвращаемого значения clock()

1 голос
/ 27 июня 2014

Я использовал небольшую программу ниже, чтобы исследовать время настенных часов и время процессора.

В моей тестовой системе это печатает

CLOCKS_PER_SEC 1000000

CPU time usage resolutio nвыглядит как 0.010000 seconds

gettimeofday изменено на 9634 uS, когда процессорное время изменяется на 0.010000

gettimeofday разрешение выглядит как 1 us

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <ctime>


int main(int argc, char** argv) {

    struct  timeval now; // wall clock times
    struct  timeval later;

    clock_t tNow = clock(); // clock measures CPU time of this Linux thread
    gettimeofday(&now, NULL); // wall clock time when CPU time first read

    clock_t tLater = tNow;
    while (tNow == tLater)
           tLater = clock(); // consume CPU time

    gettimeofday(&later, NULL); // wall clock time when CPU time has ticked

    printf("CLOCKS_PER_SEC %ld\n",CLOCKS_PER_SEC);

    double cpuRes = (double)(tLater - tNow)/CLOCKS_PER_SEC;

    printf("CPU time usage resolution looks to be %f seconds\n", cpuRes);

    unsigned long long nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL;
    nowUs += (unsigned long long)now.tv_usec;

    unsigned long long laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL;
    laterUs += (unsigned long long)later.tv_usec;

    printf("gettimeofday changed by %d uS when CPU time changed by %f seconds\n", (int)(laterUs - nowUs), cpuRes);

    // now measure resolution of gettimeofday

    gettimeofday(&now, NULL);
    later = now;

    while ((now.tv_sec  == later.tv_sec) && (now.tv_usec == later.tv_usec))
            gettimeofday(&later, NULL);

    nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL;
    nowUs += (unsigned long long)now.tv_usec;

    laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL;
    laterUs += (unsigned long long)later.tv_usec;

    printf("gettimeofday resolution looks to be %d us\n", (int)(laterUs - nowUs));

}
...