11.14
2. 返转
返转(wraparound)是指当时钟的时标计数器值到达最大值后,如果再增加就变为 0 的
过程。12 小时制的模拟时钟在每天的正午和午夜各会进行一次返转。Windows 98 在连续
运行 49 天后会因 32 位毫秒时标计数器的返转而挂起(请参见 Q216641)。当两位数的年
份返转时会发生 Y2K 问题。玛雅日历在 2012 年返转,因为玛雅人认为那就是世界末日。
UNIX 时间戳(自 UTC1970 年 1 月 1 日 00:00 起的带符号的 32 位秒数)会在 2038 年 1 月
发生返转,这可能会称为某些“历史悠久”的嵌入式系统的“世界末日”。返转的问题出
在缺少额外的位去记录数据,导致下次时间增加后的数值比上次时间的数值小。会返转的
时钟仅适用于测量持续时间小于返转间隔的时间。
例如,在 Windows 上,GetTickCount() 函数会返回一个分辨率为 1 毫秒的 32 位无符号的
整数值作为时标计数值。那么,GetTickCount() 的返回值会每 49 天返转一次。也就是说,
GetTickCount() 适用于测量那些所需时间小于 49 天的操作。如果一个程序在某个操作开始
时和结束时分别调用了 GetTickCount(),两个返回值之间的差值就是两次调用之间经过的
毫秒数。例如:
DWORD start = GetTickCount();
DoBigTask();
DWORD end = GetTickCount();
cout << "Startup took " << end-start << " ms" << endl;
C++ 实现无符号算术的方式去确保了即使在发生返转时也可以得到正确的结果。
GetTickCount() 对于记住自程序启动后所经过的时间是比较低效的。许多“历史悠久”的
服务器可以持续运行数个月甚至数年。返转的问题在于,由于缺少位数去记录返转的次
数,end-start 的结果中可能体现不出发生了返转,或是体现出一个或者多个返转。
自 Windows Vista 开始,微软加入了 GetTickCount64() 函数,它会返回一个 64 位无符号且
显示分辨率为 1 毫秒的时标计数值。GetTickCount64() 的结果只有在数百万年后才会发生
返转。这就意味着,几乎不会有人能够见证返转发生了。
3. 分辨率不是准确性
在 Windows 上,GetTickCount() 会返回一个无符号的 32 位整数值。如果一个程序在某个
操作开始和结束时分别调用了 GetTickCount(),两个返回值之间的差值就是两次调用之间
经过的毫秒单位的执行时间。因此,GetTickCount() 的分辨率是 1 毫秒。
例如,下面这段代码通过在循环中反复调用 Foo(),在 Windows 上测量了名为 Foo()
返转(wraparound)是指当时钟的时标计数器值到达最大值后,如果再增加就变为 0 的
过程。12 小时制的模拟时钟在每天的正午和午夜各会进行一次返转。Windows 98 在连续
运行 49 天后会因 32 位毫秒时标计数器的返转而挂起(请参见 Q216641)。当两位数的年
份返转时会发生 Y2K 问题。玛雅日历在 2012 年返转,因为玛雅人认为那就是世界末日。
UNIX 时间戳(自 UTC1970 年 1 月 1 日 00:00 起的带符号的 32 位秒数)会在 2038 年 1 月
发生返转,这可能会称为某些“历史悠久”的嵌入式系统的“世界末日”。返转的问题出
在缺少额外的位去记录数据,导致下次时间增加后的数值比上次时间的数值小。会返转的
时钟仅适用于测量持续时间小于返转间隔的时间。
例如,在 Windows 上,GetTickCount() 函数会返回一个分辨率为 1 毫秒的 32 位无符号的
整数值作为时标计数值。那么,GetTickCount() 的返回值会每 49 天返转一次。也就是说,
GetTickCount() 适用于测量那些所需时间小于 49 天的操作。如果一个程序在某个操作开始
时和结束时分别调用了 GetTickCount(),两个返回值之间的差值就是两次调用之间经过的
毫秒数。例如:
DWORD start = GetTickCount();
DoBigTask();
DWORD end = GetTickCount();
cout << "Startup took " << end-start << " ms" << endl;
C++ 实现无符号算术的方式去确保了即使在发生返转时也可以得到正确的结果。
GetTickCount() 对于记住自程序启动后所经过的时间是比较低效的。许多“历史悠久”的
服务器可以持续运行数个月甚至数年。返转的问题在于,由于缺少位数去记录返转的次
数,end-start 的结果中可能体现不出发生了返转,或是体现出一个或者多个返转。
自 Windows Vista 开始,微软加入了 GetTickCount64() 函数,它会返回一个 64 位无符号且
显示分辨率为 1 毫秒的时标计数值。GetTickCount64() 的结果只有在数百万年后才会发生
返转。这就意味着,几乎不会有人能够见证返转发生了。
3. 分辨率不是准确性
在 Windows 上,GetTickCount() 会返回一个无符号的 32 位整数值。如果一个程序在某个
操作开始和结束时分别调用了 GetTickCount(),两个返回值之间的差值就是两次调用之间
经过的毫秒单位的执行时间。因此,GetTickCount() 的分辨率是 1 毫秒。
例如,下面这段代码通过在循环中反复调用 Foo(),在 Windows 上测量了名为 Foo()