Функция таймера для предоставления времени в нано секундах с использованием C ++ - PullRequest
100 голосов
/ 08 ноября 2008

Я хочу рассчитать время, необходимое API для возврата значения. Время, необходимое для такого действия, находится в интервале наносекунд. Поскольку API является классом / функцией C ++, я использую timer.h для расчета того же:

  #include <ctime>
  #include <cstdio>

  using namespace std;

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

      clock_t start;
      double diff;
      start = clock();
      diff = ( std::clock() - start ) / (double)CLOCKS_PER_SEC;
      cout<<"printf: "<< diff <<'\n';

      return 0;
  }

Приведенный выше код дает время в секундах. Как получить то же самое за нано секунды и с большей точностью?

Ответы [ 16 ]

3 голосов
/ 18 января 2011

Я использую код Borland, вот код, который ti_hund дает мне несколько раз отрицательное число, но время довольно хорошее.

#include <dos.h>

void main() 
{
struct  time t;
int Hour,Min,Sec,Hun;
gettime(&t);
Hour=t.ti_hour;
Min=t.ti_min;
Sec=t.ti_sec;
Hun=t.ti_hund;
printf("Start time is: %2d:%02d:%02d.%02d\n",
   t.ti_hour, t.ti_min, t.ti_sec, t.ti_hund);
....
your code to time
...

// read the time here remove Hours and min if the time is in sec

gettime(&t);
printf("\nTid Hour:%d Min:%d Sec:%d  Hundreds:%d\n",t.ti_hour-Hour,
                             t.ti_min-Min,t.ti_sec-Sec,t.ti_hund-Hun);
printf("\n\nAlt Ferdig Press a Key\n\n");
getch();
} // end main
3 голосов
/ 08 ноября 2008

Если вам нужна точность ниже секунды, вам нужно использовать системные расширения, и вам придется сверяться с документацией для операционной системы. POSIX поддерживает до микросекунд с gettimeofday , но ничего более точного, поскольку у компьютеров нет частот выше 1 ГГц.

Если вы используете Boost, вы можете проверить boost :: posix_time .

2 голосов
/ 10 февраля 2016

Минималистичный способ копирования и вставки + ленивое использование

Если идея состоит в том, чтобы иметь минималистичную структуру, которую вы можете использовать для быстрых тестов, тогда я предлагаю вам просто скопировать и вставить в любое место файла C ++ сразу после #include. Это единственный случай, когда я жертвую форматированием в стиле Allman.

Вы можете легко настроить точность в первой строке структуры. Возможные значения: nanoseconds, microseconds, milliseconds, seconds, minutes или hours.

#include <chrono>
struct MeasureTime
{
    using precision = std::chrono::microseconds;
    std::vector<std::chrono::steady_clock::time_point> times;
    std::chrono::steady_clock::time_point oneLast;
    void p() {
        std::cout << "Mark " 
                << times.size()/2
                << ": " 
                << std::chrono::duration_cast<precision>(times.back() - oneLast).count() 
                << std::endl;
    }
    void m() {
        oneLast = times.back();
        times.push_back(std::chrono::steady_clock::now());
    }
    void t() {
        m();
        p();
        m();
    }
    MeasureTime() {
        times.push_back(std::chrono::steady_clock::now());
    }
};

Использование

MeasureTime m; // first time is already in memory
doFnc1();
m.t(); // Mark 1: next time, and print difference with previous mark
doFnc2();
m.t(); // Mark 2: next time, and print difference with previous mark
doStuff = doMoreStuff();
andDoItAgain = doStuff.aoeuaoeu();
m.t(); // prints 'Mark 3: 123123' etc...

Стандартный результат вывода

Mark 1: 123
Mark 2: 32
Mark 3: 433234

Если вы хотите получить резюме после выполнения

Если вам нужен отчет позже, потому что, например, ваш промежуточный код также записывает в стандартный вывод. Затем добавьте следующую функцию в структуру (непосредственно перед MeasureTime ()):

void s() { // summary
    int i = 0;
    std::chrono::steady_clock::time_point tprev;
    for(auto tcur : times)
    {
        if(i > 0)
        {
            std::cout << "Mark " << i << ": "
                    << std::chrono::duration_cast<precision>(tprev - tcur).count()
                    << std::endl;
        }
        tprev = tcur;
        ++i;
    }
}

Итак, вы можете просто использовать:

MeasureTime m;
doFnc1();
m.m();
doFnc2();
m.m();
doStuff = doMoreStuff();
andDoItAgain = doStuff.aoeuaoeu();
m.m();
m.s();

Который будет перечислять все метки, как и раньше, но затем после выполнения другого кода. Обратите внимание, что вы не должны использовать оба m.s() и m.t().

2 голосов
/ 24 апреля 2014

Вот хороший Boost таймер, который работает хорошо:

//Stopwatch.hpp

#ifndef STOPWATCH_HPP
#define STOPWATCH_HPP

//Boost
#include <boost/chrono.hpp>
//Std
#include <cstdint>

class Stopwatch
{
public:
    Stopwatch();
    virtual         ~Stopwatch();
    void            Restart();
    std::uint64_t   Get_elapsed_ns();
    std::uint64_t   Get_elapsed_us();
    std::uint64_t   Get_elapsed_ms();
    std::uint64_t   Get_elapsed_s();
private:
    boost::chrono::high_resolution_clock::time_point _start_time;
};

#endif // STOPWATCH_HPP


//Stopwatch.cpp

#include "Stopwatch.hpp"

Stopwatch::Stopwatch():
    _start_time(boost::chrono::high_resolution_clock::now()) {}

Stopwatch::~Stopwatch() {}

void Stopwatch::Restart()
{
    _start_time = boost::chrono::high_resolution_clock::now();
}

std::uint64_t Stopwatch::Get_elapsed_ns()
{
    boost::chrono::nanoseconds nano_s = boost::chrono::duration_cast<boost::chrono::nanoseconds>(boost::chrono::high_resolution_clock::now() - _start_time);
    return static_cast<std::uint64_t>(nano_s.count());
}

std::uint64_t Stopwatch::Get_elapsed_us()
{
    boost::chrono::microseconds micro_s = boost::chrono::duration_cast<boost::chrono::microseconds>(boost::chrono::high_resolution_clock::now() - _start_time);
    return static_cast<std::uint64_t>(micro_s.count());
}

std::uint64_t Stopwatch::Get_elapsed_ms()
{
    boost::chrono::milliseconds milli_s = boost::chrono::duration_cast<boost::chrono::milliseconds>(boost::chrono::high_resolution_clock::now() - _start_time);
    return static_cast<std::uint64_t>(milli_s.count());
}

std::uint64_t Stopwatch::Get_elapsed_s()
{
    boost::chrono::seconds sec = boost::chrono::duration_cast<boost::chrono::seconds>(boost::chrono::high_resolution_clock::now() - _start_time);
    return static_cast<std::uint64_t>(sec.count());
}
2 голосов
/ 29 августа 2012

Что вы думаете об этом:

    int iceu_system_GetTimeNow(long long int *res)
    {
      static struct timespec buffer;
      // 
    #ifdef __CYGWIN__
      if (clock_gettime(CLOCK_REALTIME, &buffer))
        return 1;
    #else
      if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &buffer))
        return 1;
    #endif
      *res=(long long int)buffer.tv_sec * 1000000000LL + (long long int)buffer.tv_nsec;
      return 0;
    }
2 голосов
/ 08 ноября 2008

Если это для Linux, я использую функцию "gettimeofday", которая возвращает структуру, которая дает секунды и микросекунды с начала эпохи. Затем вы можете использовать timersub, чтобы вычесть два значения, чтобы получить разницу во времени, и преобразовать ее в любое время с любой точностью. Однако вы указываете наносекунды и похоже, что функция clock_gettime () - это то, что вы ищете. Он помещает время в секундах и наносекундах в структуру, которую вы передаете ему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...