计算时间间隔

Windows Time

Windows time is the number of milliseconds elapsed since the system was last started. This format exists primarily for backward compatibility with 16-bit Windows. To ensure that applications designed for 16-bit Windows continue to run successfully, the GetTickCount function returns the current Windows time.

  • system timer
  • multimedia timer
  • high-resolution timer

1. system timer

// Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days.
DWORD GetTickCount();

// Retrieves the number of milliseconds that have elapsed since the system was started.
ULONGLONG GetTickCount64();

Remarks
GetTickCount and GetTickCount64 are limited to the resolution of the system timer, which is approximately 10 milliseconds to 16 milliseconds. The elapsed time retrieved by GetTickCount or GetTickCount64 includes time the system spends in sleep or hibernation.

For GetTickCount(), the elapsed time is stored as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days. To avoid this problem, use the GetTickCount64 function. Otherwise, check for an overflow condition when comparing times.

If you need a higher resolution timer, use a multimedia timer or a high-resolution timer.

2. multimedia timer

The multimedia timer services allow an application to schedule periodic timer events — that is, the application can request and receive timer messages at application-specified intervals.

Multimedia timer services allow applications to schedule timer events with the greatest resolution (or accuracy) possible for the hardware platform. These multimedia timer services allow you to schedule timer events at a higher resolution than other timer services.

These timer services are useful for applications that demand high-resolution timing. For example, a MIDI sequencer requires a high-resolution timer because it must maintain the pace of MIDI events within a resolution of 1 millisecond.

/* Retrieves the system time, in milliseconds. 
The system time is the time elapsed since Windows was started. */
DWORD timeGetTime();

使用 timeGetTime 时必须先包含多媒体库 Winmm.lib,可以在代码中添加:

#pragma comment(lib, "winmm")

#pragma comment(lib, "winmm.lib")

Remarks
The only difference between this function and the timeGetSystemTime function is that timeGetSystemTime uses the MMTIME structure to return the system time. The timeGetTime function has less overhead than timeGetSystemTime.

Note that the value returned by the timeGetTime function is a DWORD value. The return value wraps around to 0 every 2^32 milliseconds, which is about 49.71 days. This can cause problems in code that directly uses the timeGetTime return value in computations, particularly where the value is used to control code execution. You should always use the difference between two timeGetTime return values in computations.

The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine. You can use the timeBeginPeriod and timeEndPeriod functions to increase the precision of timeGetTime. If you do so, the minimum difference between successive values returned by timeGetTime can be as large as the minimum period value set using timeBeginPeriod and timeEndPeriod.

Use the QueryPerformanceCounter and QueryPerformanceFrequency functions to measure short time intervals at a high resolution.

3. high-resolution timer

A counter is a general term used in programming to refer to an incrementing variable. Some systems include a high-resolution performance counter that provides high-resolution elapsed times.

If a high-resolution performance counter exists on the system, you can use the QueryPerformanceFrequency function to express the frequency, in counts per second. The value of the count is processor dependent. On some processors, for example, the count might be the cycle rate of the processor clock.

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter. By calling this function at the beginning and end of a section of code, an application essentially uses the counter as a high-resolution timer. For example, suppose that QueryPerformanceFrequency indicates that the frequency of the high-resolution performance counter is 50,000 counts per second. If the application calls QueryPerformanceCounter immediately before and immediately after the section of code to be timed, the counter values might be 1500 counts and 3500 counts, respectively. These values would indicate that .04 seconds (2000 counts) elapsed while the code executed.

/* Retrieves the frequency of the performance counter. The frequency of the 
performance counter is fixed at system boot and is consistent across all processors.
Therefore,  the frequency need only be queried upon application initialization, 
and the result  can be cached. */
BOOL QueryPerformanceFrequency(
  LARGE_INTEGER *lpFrequency
);

Parameters
lpFrequency

A pointer to a variable that receives the current performance-counter frequency, in counts per second. If the installed hardware doesn’t support a high-resolution performance counter, this parameter can be zero (this will not occur on systems that run Windows XP or later).

Return value
If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. On systems that run Windows XP or later, the function will always succeed and will thus never return zero.

/* Retrieves the current value of the performance counter, which is a high 
resolution (<1us) time stamp that can be used for time-interval measurements. */
BOOL QueryPerformanceCounter(
  LARGE_INTEGER *lpPerformanceCount
);

Parameters
lpPerformanceCount

A pointer to a variable that receives the current performance-counter value, in counts.

Return value
If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. On systems that run Windows XP or later, the function will always succeed and will thus never return zero.

Example:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

inline DWORD GetTick_ms()
{
#if defined(_MSC_VER)
	LARGE_INTEGER tFrequency = { 0 };
	LARGE_INTEGER tPerformanceCount = { 0 };
	// 获取晶振频率
	QueryPerformanceFrequency(&tFrequency);
	// 获取晶振数
	QueryPerformanceCounter(&tPerformanceCount);
	// 计算获得时间片
	return (DWORD)((tPerformanceCount.QuadPart * 1000 / tFrequency.QuadPart) & 0x00000000FFFFFFFF);
#else
	struct timespec tTimeTick = {0};
	clock_gettime(CLOCK_MONOTONIC, &tTimeTick);
	return (DWORD)((tTimeTick.tv_sec * 1000) + (tTimeTick.tv_nsec / 1000000));
#endif
}

inline DWORD GetTick_us()
{
	LARGE_INTEGER tFrequency = { 0 };
	LARGE_INTEGER tPerformanceCount = { 0 };
	// 获取晶振频率
	QueryPerformanceFrequency(&tFrequency);
	// 获取晶振数
	QueryPerformanceCounter(&tPerformanceCount);
	// 计算获得时间片
	return (DWORD)((tPerformanceCount.QuadPart * 1000 * 1000 / tFrequency.QuadPart) & 0x00000000FFFFFFFF);
}

inline DWORD GetTick_ns()
{
	LARGE_INTEGER tFrequency = { 0 };
	LARGE_INTEGER tPerformanceCount = { 0 };
	// 获取晶振频率
	QueryPerformanceFrequency(&tFrequency);
	// 获取晶振数
	QueryPerformanceCounter(&tPerformanceCount);
	// 计算获得时间片
	return (DWORD)((tPerformanceCount.QuadPart * 1000 * 1000 * 1000 / tFrequency.QuadPart) & 0x00000000FFFFFFFF);
}


int main()
{
	// 获取晶振频率
	LARGE_INTEGER tFrequency = { 0 };
	QueryPerformanceFrequency(&tFrequency);
	printf("晶振频率 : %ld Hz\n\n", tFrequency.QuadPart);

	// test ms
	int nIndex = 0;
	while (nIndex++ < 3)
	{
		DWORD dwTime1 = GetTick_ms();

		Sleep(1000); //ms

		DWORD dwTime2 = GetTick_ms();

		printf("time interval : %d ms\n\n", dwTime2 - dwTime1);
	}

	// test us
	nIndex = 0;
	while (nIndex++ < 3)
	{
		DWORD dwTime1 = GetTick_us();

		Sleep(1000); //ms

		DWORD dwTime2 = GetTick_us();

		printf("time interval : %d us\n\n", dwTime2 - dwTime1);
	}

	// test ns
	nIndex = 0;
	while (nIndex++ < 3)
	{
		DWORD dwTime1 = GetTick_ns();

		Sleep(1000); //ms

		DWORD dwTime2 = GetTick_ns();

		printf("time interval : %d ns\n\n", dwTime2 - dwTime1);
	}
	
	system("pause");
	return 0;
}

output:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值