我正在开发一个需要详细时序信息的 C++ 应用程序,精确到毫秒级。
time()我们打算使用 中的标准函数来收集秒精度的时间<ctime>。我们还想收集自上一秒给定的毫秒数time()。  
有谁知道获取此信息的便捷方法?
我正在开发一个需要详细时序信息的 C++ 应用程序,精确到毫秒级。
time()我们打算使用 中的标准函数来收集秒精度的时间<ctime>。我们还想收集自上一秒给定的毫秒数time()。  
有谁知道获取此信息的便捷方法?
如果底层平台支持,Boost.DateTime 具有毫秒和纳秒表示。当它使用平台特定的代码时,它会将这些细节排除在您的代码之外。
如果这很重要,他们确实有另一种方法来进行平台无关的亚秒级分辨率。 这个页面有几段讲述了如何做到这一点。
(来自页面)
例如,假设我们要使用表示十分之一秒的计数来构建。也就是说,每个刻度是 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
这个问题没有可移植的解决方案,因为 ANSI C 没有定义标准的毫秒精度时间函数。如果您使用的是 Windows,则可以使用 GetTickCount()、timeGetTime() 或 QueryPerformanceCounter()/QueryPerformanceFrequency()。请记住,这些具有不同的准确性和不同的运行时成本。
其他操作系统中还有其他类似的功能;我不确定他们在我的脑海中是什么。
Windows 中的GetTickCount gettimeofday在Windows 中的 *nix QueryPerformanceCounter以获得更好的分辨率(尽管 GetTickCount 应该这样做)
如果你在 Unix 上,gettimeofday()将返回秒和微秒,直到系统时钟的分辨率。
int gettimeofday(struct timeval *tv, struct timezone *tz);
struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};
适用于英特尔处理器的高分辨率、低开销时序
如果您使用的是 Intel 硬件,以下是读取 CPU 实时指令计数器的方法。它会告诉您自处理器启动以来执行的 CPU 周期数。这可能是您可以获得的用于性能测量的最细粒度的计数器。
请注意,这是 CPU 周期数。在 linux 上,您可以从 /proc/cpuinfo 获取 CPU 速度,然后除以获取秒数。将其转换为双精度非常方便。
当我在我的盒子上运行它时,我得到
11867927879484732 11867927879692217 调用 printf 花了这么长时间:207485
这是提供大量详细信息的英特尔开发人员指南。
#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);
}
正如其他人所说,没有一种便携的方法可以做到这一点。
我所做的(在 msvc++ 和 linux/g++ 上)是使用以下类,在 Windows 上使用 QueryPerformanceCounter,在 Linux 上使用 gettimeofday。这是一个计时器类,可以让您了解两次通话之间经过的时间。您可能需要对其进行修改以满足您的需要。
#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
      };
   };
}
#include <ctime>
clock_t elapsed = static_cast<double>(clock() / CLOCKS_PER_SEC);
elapsed 将是经过的处理器时间,以秒为单位。
分辨率取决于操作系统,但在大多数系统上通常优于毫秒分辨率。
标头中没有的任何内容都(c)time.h需要特定于操作系统的方法。我相信所有这些方法都是第二个解决方案。
你在什么操作系统上工作?
如果适用于 Windows,请查看 QueryPerformanceCounter 方法。
Intel 的Threading Building Blocks 库对此有一个功能,但 TBB 目前仅在 Intel 和克隆上可用(也就是说,它在 SPARC、PowerPC、ARM 等上不可用)