c++ получить миллисекунды с некоторой даты

Мне нужен какой-то способ в C++, чтобы отслеживать количество миллисекунд с момента выполнения программы. И мне нужна точность в миллисекундах. (В моем гугле я нашел много людей, которые сказали, что включают время.h, а затем умножьте выход time() на 1000 ... это не сработает.)

9 ответов


посмотреть std::clock()


clock было предложено несколько раз. Это имеет две проблемы. Во-первых, это часто не имеет разрешения даже близко к МС (10-20 МС скорее всего). Во-вторых, некоторые его реализации (например, Unix и аналогичные) возвращают время процессора, в то время как другие (например, Windows) вернуть время стены.

вы действительно не сказали, Хотите ли вы время стены или время процессора, что затрудняет дать действительно хороший ответ. В Windows вы можете использовать GetProcessTimes. Это даст вам время ядра и пользователя CPU напрямую. Он также сообщит вам, когда был создан процесс, поэтому, если вы хотите миллисекунды времени стены с момента создания процесса, вы можете вычесть время создания процесса из текущего времени (GetSystemTime). QueryPerformanceCounter уже говорилось. Это имеет несколько собственных странностей - например, в некоторых реализациях он извлекает время из счетчика циклов процессоров, поэтому его частота изменяется когда / если скорость процессора изменяется. Другие реализации считываются с таймера 1.024 МГц материнской платы, который делает не варьируются в зависимости от скорости процессора (и условия, при которых они используются, не совсем очевидны).

в Unix вы можете использовать GetTimeOfDay просто получить время стены с (по крайней мере, возможность) относительно высокой точностью. Если вам нужно время для процесса, вы можете использовать times или getrusage (последнее новые и дает более полную информацию, которая также может быть более точным).

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


включить время.h, а затем используйте функцию clock (). Он возвращает количество тактов, прошедших с момента запуска программы. Просто разделите его на "CLOCKS_PER_SEC", чтобы получить количество секунд, затем вы можете умножить на 1000, чтобы получить количество миллисекунд.


некоторые кросс-платформенное решение. Этот код использовался для какого-то бенчмаркинга:

#ifdef WIN32
  LARGE_INTEGER g_llFrequency = {0};
  BOOL g_bQueryResult = QueryPerformanceFrequency(&g_llFrequency);
#endif

//...

long long osQueryPerfomance()
{
#ifdef WIN32
  LARGE_INTEGER llPerf = {0};
  QueryPerformanceCounter(&llPerf);
  return llPerf.QuadPart * 1000ll / ( g_llFrequency.QuadPart / 1000ll);
#else
  struct timeval stTimeVal;
  gettimeofday(&stTimeVal, NULL);
  return stTimeVal.tv_sec * 1000000ll + stTimeVal.tv_usec;
#endif
}

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

  • разрешение не очень хорошо для систем GNU. Очень жаль.

  • заботиться о литье все двойной перед выполнением делений и назначений.

  • счетчик как 32-битное число в GNU 32 бит, который может быть довольно раздражающим для длительных программ.

есть альтернативы, использующие "время стены", которые дают лучшее разрешение, как в Windows, так и в Linux. Но, как указано в руководстве libc:Если вы пытаетесь оптимизировать свою программу или измерить ее эффективность, очень полезно знать, сколько процессорного времени она использует. Для этого календарное время и истекшее время бесполезны, потому что процесс может тратить время на ожидание ввода-вывода или для других процессов использовать CPU.


вот решение C++0x и пример почему clock() может не делать то, что вы думаете.

#include <chrono>
#include <iostream>
#include <cstdlib>
#include <ctime>

int main()
{
   auto start1 = std::chrono::monotonic_clock::now();
   auto start2 = std::clock();

   sleep(1);

   for( int i=0; i<100000000; ++i);

   auto end1 = std::chrono::monotonic_clock::now();
   auto end2 = std::clock();

   auto delta1 = end1-start1;
   auto delta2 = end2-start2;

   std::cout << "chrono: " << std::chrono::duration_cast<std::chrono::duration<float>>(delta1).count() << std::endl;

   std::cout << "clock: " << static_cast<float>(delta2)/CLOCKS_PER_SEC << std::endl;
}

на моей системе это выводит:

chrono: 1.36839
clock: 0.36

Вы заметите clock() метод отсутствует второй. Проницательный наблюдатель мог бы также заметить, что clock() похоже, имеет меньшее разрешение. В моей системе он тикает в 12 мс инкременты, ужасное разрешение.

если вы не можете или не хотите использовать C++0x, взгляните на импульс.Датавремяptime microsec_clock::universal_time().


это не конкретный C++ (ни портативный), но вы можете сделать:

SYSTEMTIME systemDT;

В Windows.

оттуда вы можете получить доступ к каждому члену systemDT struct.

вы можете записать время запуска программы и сравнить текущее время с записанным временем (systemDT и systemDTtemp, например).

чтобы обновить, вы можете позвонить GetLocalTime(&systemDT);

чтобы получить доступ к каждому члену, вы бы сделали systemDT.wHour, systemDT.wMinute, systemDT.wMilliseconds.

чтобы получить больше информации о системное время.


вы хотите настенные часы, время процессора или какое-то другое измерение? Кроме того, что это за платформа? Нет универсального портативного способа получить больше точности, чем time() и clock() дам тебе, но...

  • в большинстве систем Unix, вы можете использовать gettimeofday() и/или clock_gettime(), которые дают хотя бы микросекундную точность и доступ к различным таймерам;
  • Я не так хорошо знаком с Windows, но один из эти функции наверное, то, что вы хотите.

вы можете попробовать этот код (получить из исходного кода шахматного движка StockFish (GPL)):

#include <iostream>
#include <stdio>

#if !defined(_WIN32) && !defined(_WIN64) // Linux - Unix
    #  include <sys/time.h>
    typedef timeval sys_time_t;
    inline void system_time(sys_time_t* t) {
        gettimeofday(t, NULL);
    }
    inline long long time_to_msec(const sys_time_t& t) {
        return t.tv_sec * 1000LL + t.tv_usec / 1000;
    }
    #else // Windows and MinGW
    #  include <sys/timeb.h>
    typedef _timeb sys_time_t;
    inline void system_time(sys_time_t* t) { _ftime(t); }
    inline long long time_to_msec(const sys_time_t& t) {
        return t.time * 1000LL + t.millitm;
    }
#endif

struct Time {
    void restart() { system_time(&t); }
    uint64_t msec() const { return time_to_msec(t); }
    long long elapsed() const {
        return long long(current_time().msec() - time_to_msec(t));
    }
    static Time current_time() { Time t; t.restart(); return t; }
private:
    sys_time_t t;
};

int main() {
    sys_time_t t;
    system_time(&t);
    long long currentTimeMs = time_to_msec(t);
    std::cout << "currentTimeMs:" << currentTimeMs << std::endl;

    Time time = Time::current_time();
    for (int i = 0; i < 1000000; i++) {
        //Do something
    }
    long long e = time.elapsed();
    std::cout << "time elapsed:" << e << std::endl;

    getchar();  // wait for keyboard input
}