C++ timing, milliseconds since last whole second

2020-06-20 05:25发布

I'm working on a C++ application that needs detailed timing information, down to the millisecond level.

We intend to gather the time to second accuracy using the standard time() function in <ctime>. We would like to additionally gather the milliseconds elapsed since the last second given by time().

Does anyone know a convenient method for obtaining this information?

10条回答
Juvenile、少年°
2楼-- · 2020-06-20 06:02

As other have said, there is not a portable way to do this.

What I do (On msvc++ and linux/g++) is I use the following class that use QueryPerformanceCounter on Windows and gettimeofday on Linux. It's a timer class that can get you the elapsed time between two calls. You might want to modify it to fits your needs.

#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
      };
   };
}
查看更多
何必那么认真
3楼-- · 2020-06-20 06:03

GetTickCount in Windows gettimeofday in *nix QueryPerformanceCounter in Windows for better resolution (though GetTickCount should do it)

查看更多
ら.Afraid
4楼-- · 2020-06-20 06:04

If you're on Unix, gettimeofday() will return seconds and microseconds, up to the resolution of the system clock.

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

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};
查看更多
劳资没心,怎么记你
5楼-- · 2020-06-20 06:07
#include <ctime>

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

elapsed will be the elapsed processor time, in seconds.

resolution is operation system dependent, but is generally better than millisecond resolution on most systems.

查看更多
The star\"
6楼-- · 2020-06-20 06:11

High Resolution, Low Overhead Timing for Intel Processors

If you're on Intel hardware, here's how to read the CPU real-time instruction counter. It will tell you the number of CPU cycles executed since the processor was booted. This is probably the finest-grained counter you can get for performance measurement.

Note that this is the number of CPU cycles. On linux you can get the CPU speed from /proc/cpuinfo and divide to get the number of seconds. Converting this to a double is quite handy.

When I run this on my box, I get

11867927879484732
11867927879692217
it took this long to call printf: 207485

Here's the Intel developer's guide that gives tons of detail.

#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);
}
查看更多
冷血范
7楼-- · 2020-06-20 06:11

Look into the QueryPerformanceCounter methods if this is for Windows.

查看更多
登录 后发表回答