Почему функция clock () в C от & lt; time.h & gt; заголовок возвращает только значения тактовых импульсов с шагом в 10 тысяч? [Дубликат]

Примером этого исключаемого исключения является: Когда вы пытаетесь проверить что-то, это null.

Например:

string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)

if (testString.Length == 0) // Throws a nullreferenceexception
{
    //Do something
} 

Время выполнения .NET исключение NullReferenceException при попытке выполнить действие над чем-то, что не было инстанцировано, т.е. код выше.

По сравнению с ArgumentNullException, которое обычно выбрано как защитная мера, если метод ожидает, что то, что происходит

Дополнительная информация находится в C # NullReferenceException и Null Parameter .

7
задан Andrew Marshall 21 December 2011 в 20:05
поделиться

4 ответа

В POSIX имеется ряд более точных таймеров.

  • gettimeofday() - официально устаревший, но очень широко доступный; микросекундное разрешение.
  • clock_gettime() - замена для gettimeofday() (но не обязательно настолько широко доступная; на старой версии Solaris требуется -lposix4 для ссылки) с разрешением наносекунд.

Существуют другие субсекундные таймеры большей или меньшей древности, переносимости и разрешения, в том числе:

  • ftime() - разрешение в миллисекундах (помечено «наследие» в POSIX 2004, а не в POSIX 2008).
  • clock() - о котором вы уже знаете. Обратите внимание, что он измеряет время процессора, а не истекшее (время настенных часов).
  • times() - CLK_TCK или HZ. Обратите внимание, что это измеряет время процессора для родительского и дочернего процессов.

Не используйте ftime() или times(), если нет ничего лучше. Окончательный резерв, но не отвечающий вашим непосредственным требованиям, -

  • time() - разрешение в одну секунду.

Кнопка clock() в единицах CLOCKS_PER_SEC, которые должны быть 1,000,000 POSIX, но приращение может происходить реже (100 раз в секунду была одной общей частотой). Возвращаемое значение должно быть определено CLOCKS_PER_SEC, чтобы получить время в секундах.

8
ответ дан Jonathan Leffler 26 August 2018 в 21:37
поделиться

Самый точный (но очень не переносимый) способ измерения времени - подсчитать тики CPU.

Например, на x86

 unsigned long long int asmx86Time ()
 {
   unsigned long long int realTimeClock = 0;
   asm volatile ( "rdtsc\n\t"         
                  "salq $32, %%rdx\n\t"    
                  "orq %%rdx, %%rax\n\t"   
                  "movq %%rax, %0"         
                  : "=r" ( realTimeClock ) 
                  : /* no inputs */
                  : "%rax", "%rdx" );
   return realTimeClock;
 }

 double cpuFreq ()
 {
   ifstream file ( "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" );
   string sFreq; if ( file ) file >> sFreq;
   stringstream ssFreq ( sFreq ); double freq = 0.;
   if ( ssFreq ) { ssFreq >> freq; freq *= 1000; } // kHz to Hz
   return freq;
 }

 // Timing

 unsigned long long int asmStart = asmx86Time ();
 doStuff ();
 unsigned long long int asmStop  = asmx86Time ();
 float asmDuration = ( asmStop - asmStart ) / cpuFreq ();

Если у вас нет x86, вам придется переписать код ассемблера в соответствии с вашим процессором. Если вам нужна максимальная точность, это, к сожалению, единственный способ пойти ... иначе используйте clock_gettime ().

1
ответ дан FGH 26 August 2018 в 21:37
поделиться

В man-странице clock () на платформах POSIX значение макроса CLOCKS_PER_SEC должно быть 1000000. Как вы говорите, возвращаемое значение, которое вы получаете от clock (), кратно 10000, это означает, что разрешение составляет 10 мс.

Также обратите внимание, что clock () в Linux возвращает приблизительное время процессора, используемое программой. В Linux снова отображается статистика планировщика при запуске планировщика на частоте CONFIG_HZ. Поэтому, если периодический таймер равен 100 Гц, вы получаете статистику потребления процессорного времени процессора с разрешением 10 мс.

Измерения настенной шкалы не связаны этим и могут быть намного точнее. clock_gettime (CLOCK_MONOTONIC, ...) на современной Linux-системе обеспечивает наносекундное разрешение.

1
ответ дан janneb 26 August 2018 в 21:37
поделиться

Я согласен с решением Джонатана. Вот реализация clock_gettime () с точностью до наносекунд.

//Import 
 #define _XOPEN_SOURCE 500
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 #include <sys/time.h>


 int main(int argc, char *argv[])
 {   
     struct timespec ts;
     int ret;
     while(1)
     {
         ret = clock_gettime (CLOCK_MONOTONIC, &ts);
         if (ret) 
         {
             perror ("clock_gettime");
             return;
         }
         ts.tv_nsec += 20000; //goto sleep for 20000 n
         printf("Print before sleep tid%ld %ld\n",ts.tv_sec,ts.tv_nsec );
        // printf("going to sleep tid%d\n",turn );
         ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME,&ts, NULL);

     }
 }

Хотя трудно достичь точности ns, но это можно использовать для получения точности менее чем за микросекунды (700-900 нс). printf выше используется, чтобы просто распечатать поток # (для распечатки заявления потребуется всего 2-3 микросекунды).

-1
ответ дан Scissor 26 August 2018 в 21:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: