Синхронизация C ++, миллисекунды с последней секунды - PullRequest
5 голосов
/ 23 сентября 2008

Я работаю над приложением C ++, которому нужна подробная информация о времени, вплоть до миллисекундного уровня.

Мы собираемся собрать время с точностью до секунды, используя стандартную функцию time() в <ctime>. Мы хотели бы дополнительно собрать миллисекунды, прошедшие с последней секунды, заданной time().

Кто-нибудь знает удобный способ получения этой информации?

Ответы [ 10 ]

11 голосов
/ 23 сентября 2008

Boost.DateTime имеет представление в миллисекундах и наносекундах IF , базовая платформа поддерживает их. В то время как он использует специфичный для платформы код, он скрывает эти детали от вашего кода.

Если это важно, у них есть другой способ сделать независимое от платформы разрешение за секунду. Эта страница пара абзацев ниже рассказывает о том, как это сделать.

(со страницы)

Например, предположим, что мы хотим построить, используя счетчик, который представляет десятые доли секунды. То есть каждый тик равен 0,1 секунды.

int number_of_tenths = 5;
//create a resolution independent count -- divide by 10 since there are 
//10 tenths in a second.  
int count = number_of_tenths*(time_duration::ticks_per_second()/10);
time_duration td(1,2,3,count); //01:02:03.5 //no matter the resolution settings
8 голосов
/ 23 сентября 2008

Нет портативного решения этой проблемы, поскольку ANSI C не определяет стандартную функцию времени с точностью до миллисекунды. Если вы используете Windows, вы можете использовать GetTickCount (), timeGetTime () или QueryPerformanceCounter () / QueryPerformanceFrequency (). Имейте в виду, что они имеют разную точность и разные затраты времени выполнения.

Есть другие подобные функции в других операционных системах; Я не уверен, что они с моей головы.

3 голосов
/ 23 сентября 2008

GetTickCount в Windows gettimeofday in * nix QueryPerformanceCounter в Windows для лучшего разрешения (хотя GetTickCount должен это делать)

2 голосов
/ 23 сентября 2008

Как уже говорили другие, для этого нет переносимого способа.

Что я делаю (в msvc ++ и linux / g ++) - я использую следующий класс, который использует QueryPerformanceCounter в Windows и gettimeofday в Linux. Это класс таймера, который может дать вам истекшее время между двумя вызовами. Возможно, вы захотите изменить его в соответствии с вашими потребностями.

#if defined(_MSC_VER)
#  define NOMINMAX // workaround un bug dans windows.h qui define des macros
                   // "min" et "max" qui entrent en conflit avec la STL.
#  include <windows.h>
#else
#  include <sys/time.h>
#endif

namespace Utils
{

   /**
    * Implémente un chronométre qui mesure le temps etre deux appels.
    */
   class CTimer
   {
   private:
#     if defined(_MSC_VER)
         LARGE_INTEGER m_depart;
#     else
         timeval m_depart;
#     endif

   public:
      /**
       * Démarre le timer.
       * 
       * Cette fonction sert à démarrer le timer. Si le timer est  déja
       * démarrer, elle le redémarre simplement.
       */
      inline void start()
      {
#        if defined(_MSC_VER)
            QueryPerformanceCounter(&m_depart);
#        else
            gettimeofday(&m_depart, 0);
#        endif

      };

      /**
       * Retourne le nombre de secondes depuis le départ du timer.
       * 
       * @return Nombre de secondes écoulés depuis le départ du timer
       */
      inline float GetSecondes() const
      {
#        if defined(_MSC_VER)
            LARGE_INTEGER now;
            LARGE_INTEGER freq;

            QueryPerformanceCounter(&now);
            QueryPerformanceFrequency(&freq);

            return (now.QuadPart - m_depart.QuadPart) / static_cast<float>(freq.QuadPart);
#        else
            timeval now;
            gettimeofday(&now, 0);

            return now.tv_sec - m_depart.tv_sec + (now.tv_usec - m_depart.tv_usec) / 1000000.0f;
#        endif
      };
   };
}
2 голосов
/ 23 сентября 2008

Если вы работаете в Unix, gettimeofday () вернет секунды и микросекунды, вплоть до разрешения системных часов.

int gettimeofday(struct timeval *tv, struct timezone *tz);

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};
2 голосов
/ 23 сентября 2008

Высокое разрешение, низкая нагрузка для процессоров Intel

Если вы используете аппаратное обеспечение Intel, здесь показано, как считать счетчик команд процессора в режиме реального времени. Он сообщит вам количество циклов ЦП, выполненных с момента загрузки процессора. Вероятно, это самый точный счетчик, который вы можете получить для измерения производительности.

Обратите внимание, что это количество циклов ЦП. В Linux вы можете получить скорость процессора из / proc / cpuinfo и разделить, чтобы получить количество секунд. Преобразование в двойное число весьма удобно.

Когда я запускаю это на своей коробке, я получаю

11867927879484732
11867927879692217
it took this long to call printf: 207485

Вот руководство для разработчиков Intel *1013*, в котором содержится множество деталей.

#include < stdio.h >  // stackoverflow bug: pre tag eats the filenames,
#include < stdint.h > // so i had to put spaces in the angle brackets

inline uint64_t rdtsc() {
    uint32_t lo, hi;
    __asm__ __volatile__ (
      "xorl %%eax, %%eax\n"
      "cpuid\n"
      "rdtsc\n"
      : "=a" (lo), "=d" (hi)
      :
      : "%ebx", "%ecx");
    return (uint64_t)hi << 32 | lo;
}

main()
{
    unsigned long long x;
    unsigned long long y;
    x = rdtsc();
    printf("%lld\n",x);
    y = rdtsc();
    printf("%lld\n",y);
    printf("it took this long to call printf: %lld\n",y-x);
}
1 голос
/ 23 сентября 2008
#include <ctime>

clock_t elapsed = static_cast<double>(clock() / CLOCKS_PER_SEC);

истекшее время процессора, в секундах.

Разрешение

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

0 голосов
/ 23 сентября 2008

Библиотека Intel Threading Building Blocks имеет функцию для этого, но TBB в настоящее время доступна только для Intel и клонов (то есть она недоступна для SPARC, PowerPC, ARM и т. Д.)

0 голосов
/ 23 сентября 2008

Все, что не в заголовке (c)time.h, требует специфических для ОС методов. Я считаю, что все эти методы являются вторым решением.

В какой ОС вы работаете?

0 голосов
/ 23 сентября 2008

Посмотрите на методы QueryPerformanceCounter, если это для Windows.

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