Время работы вычислительного алгоритма в C

Я использую библиотеку time.h в c, чтобы найти время, необходимое для запуска алгоритма. Структура кода примерно следующая: -

#include <time.h>

int main()
{
  time_t start,end,diff;

  start = clock();
    //ALGORITHM COMPUTATIONS
  end = clock();
  diff = end - start;
  printf("%d",diff);
  return 0;
}

Значения для начала и конца всегда равны нулю. Дело в том, что функция clock() не работает? Пожалуйста помоги. Заранее спасибо.


person AAB    schedule 16.09.2011    source источник
comment
см. SO-ссылка для примера gettimeofday   -  person Fredrik Pihl    schedule 17.09.2011
comment
Что это за платформа? Если это платформа x86, вы можете/должны использовать TSC.   -  person David Schwartz    schedule 17.09.2011
comment
Вы пытаетесь найти реальное время (то есть, сколько секунд, измеренное вашим секундомером) или тактовые циклы (сколько операций процессора)?   -  person Foo Bah    schedule 17.09.2011


Ответы (4)


Не то, чтобы это не работало. На самом деле, это так. Но это неправильный способ измерения времени, поскольку функция clock () возвращает приблизительное время процессора, используемое программой. Я не уверен насчет других платформ, но в Linux следует использовать clock_gettime () с флагом CLOCK_MONOTONIC - это даст вам реальное прошедшее время стены. Кроме того, вы можете прочитать TSC, но имейте в виду, что это не сработает, если у вас несколько -процессорная система и ваш процесс не привязан к конкретному ядру. Если вы хотите проанализировать и оптимизировать свой алгоритм, я бы порекомендовал вам использовать некоторые инструменты измерения производительности. Я уже давно пользуюсь Intel vTune и вполне доволен. Он не только покажет вам, какая часть использует больше всего циклов, но и выделит проблемы с памятью, возможные проблемы с параллелизмом и т. д. Вы можете быть очень удивлены результатами. Например, большая часть циклов ЦП может быть потрачена на ожидание шины памяти. Надеюсь, поможет!

ОБНОВЛЕНИЕ: На самом деле, если вы используете более поздние версии Linux, он может предоставить CLOCK_MONOTONIC_RAW, который представляет собой аппаратные часы, которые не подлежат настройке NTP. Вот небольшой фрагмент кода, который вы можете использовать:

person Community    schedule 16.09.2011
comment
Ваш ответ страдает от того, что Весь мир - это Linux/i386 (исторически Весь мир - это VAX). На плакате был показан чистый код C89. Мы должны предположить, что он хочет портативное решение, если не указано иное. Я приветствую ваше замечание о точности clock(); но получение системной специфики с помощью TSC, многоядерных процессоров и т. д., вероятно, не поможет кому-то, кто делает первые шаги в C (например, забытый ‹stdio.h› :-) - person Jens; 17.09.2011
comment
@Jens: Ты не прав в этом. clock_gettime() так же переносим, ​​как и Linux (и соответствует SUSv2 и POSIX.1-2001), в Windows есть QueryPerformanceCounter и QueryPerformanceFrequency, в Mac — mach_absolute_time. На всех платформах нет простых в использовании часов с наносекундной точностью. И функция clock () практически бесполезна. - person ; 17.09.2011
comment
Пожалуйста, поймите, что вы делаете много предположений. Все, о котором вы упоминаете, кроме clock(), зависит от ОС: Linux, clock_gettime, TSC, vTune. Что делать, если OP находится на Solaris/Sparc? AIX/RS6000? РУКА? PowerPC? MacOS? Тогда большая часть вашего ответа — пустая трата времени для вас обоих. Целесообразно сначала попросить ОП изложить свои требования, прежде чем делать предположения. Или хотя бы четко изложите свои предположения. Это все. - person Jens; 17.09.2011

Обратите внимание, что clock() возвращает время выполнения в тактах часов, а не время настенных часов. Разделите разницу двух значений clock_t на CLOCKS_PER_SEC, чтобы преобразовать разницу в секунды. Фактическое значение CLOCKS_PER_SEC зависит от качества реализации. Если оно низкое (скажем, 50), ваш процесс должен будет работать в течение 20 мс, чтобы вызвать ненулевое возвращаемое значение из clock(). Убедитесь, что ваш код работает достаточно долго, чтобы увидеть увеличение clock().

person Jens    schedule 16.09.2011
comment
CLOCKS_PER_SEC равно 1000000 и не зависит от частоты ЦП, как определено POSIX. - person ; 17.09.2011
comment
Это верно только в том случае, если ОС соответствует расширению POSIX XSI. ISO C99 не делает такого заявления о значении CLOCKS_PER_SEC, и на плакате не указана какая-либо ОС. - person Jens; 17.09.2011

Я обычно делаю так:

clock_t start = clock();
clock_t end;

//algo

end = clock();
printf("%f", (double)(end - start));
person Community    schedule 16.09.2011
comment
Тогда вы, скорее всего, не выполняете достаточно инструкций, чтобы увеличить время выполнения. Попробуйте разместить длинный цикл for/while (я бы сделал простой for (int i = 0; i‹= 100000; ++i) { // было бы неплохо выполнить что-нибудь и здесь } - person ; 17.09.2011
comment
Функция gettimeofday работает..... по крайней мере дает ненулевое значение. Я пытаюсь получить время, необходимое для сортировки массива..... функция clock() отлично работает, увеличивая размер сортируемого массива. - person AAB; 17.09.2011

Рассмотрим код ниже:

#include <stdio.h>
#include <time.h>

int main()
{
    clock_t t1, t2;
    t1 = t2 = clock();

    // loop until t2 gets a different value
    while(t1 == t2)
        t2 = clock();

    // print resolution of clock()
    printf("%f ms\n", (double)(t2 - t1) / CLOCKS_PER_SEC * 1000);

    return 0;
}

Выход:

$ ./a.out 
10.000000 ms

Возможно, ваш алгоритм работает меньше времени, чем это. Используйте gettimeofday для таймера с более высоким разрешением.

person Fredrik Pihl    schedule 16.09.2011