CPU speed (MHz) and high precision latency (microsecond)

Source: Internet
Author: User
CPU speed (MHz) and high precision latency (microsecond)

(Browsing 20979 times)

Victor Chen, (C ++ fans)

I. High-Precision latency is the basis of CPU speed measurement
Windows has a very high-precision timer in microseconds, but different systems have different timer frequencies, which may be related to hardware and operating systems.

You can use the API function queryperformancefrequency to obtain the timer frequency.
You can use the API function queryperformancecounter to obtain the current value of the timer.
Based on the time to be delayed and the timer frequency, you can calculate the number of cycles of the time timer to be delayed.
In the loop, queryperformancecounter is used to read the timer value without stopping until the cycle is completed after a specified number of cycles. This achieves the goal of High Precision latency.

High-Precision latency program, parameters: microseconds:

Void delayus (_ int64 us)
{
Large_integer currticks, tickscount;

Queryperformancefrequency (& tickscount );
Queryperformancecounter (& currticks );

Tickscount. quadpart = tickscount. quadpart * US/000000i64;
Tickscount. quadpart + = currticks. quadpart;

While (currticks. quadpart <tickscount. quadpart)
Queryperformancecounter (& currticks );
}

2. Procedure
The rdtsc Assembly command can be used to obtain the value of the CPU Internal timer. Each time a CPU cycle passes, this timer will add one.
If the number of CPU cycles is obtained within a period of time, the CPU operating frequency = the number of cycles/Time

In order not to disturb other processes and threads, you must set the highest priority.
The following function sets the highest priority for the current process and thread.
Setpriorityclass (getcurrentprocess (), realtime_priority_class );
Setthreadpriority (getcurrentthread (), thread_priority_time_critical );

Source code of the CPU speed measuring program. This program calculates the operating frequency by the number of cycles that the CPU passes in 1/16 seconds, in MHz:

Int cpu_frequency (void) // MHz
{
Large_integer currticks, tickscount;
_ Int64 istartcounter, istopcounter;

DWORD dwoldprocessp = getpriorityclass (getcurrentprocess ());
DWORD dwoldthreadp = getthreadpriority (getcurrentthread ());

Setpriorityclass (getcurrentprocess (), realtime_priority_class );
Setthreadpriority (getcurrentthread (), thread_priority_time_critical );

Queryperformancefrequency (& tickscount );
Queryperformancecounter (& currticks );

Tickscount. quadpart/= 16;
Tickscount. quadpart + = currticks. quadpart;

ASM rdtsc
ASM mov dword ptr istartcounter, eax
ASM mov dword ptr (istartcounter + 4), EDX

While (currticks. quadpart <tickscount. quadpart)
Queryperformancecounter (& currticks );

ASM rdtsc
ASM mov dword ptr istopcounter, eax
ASM mov dword ptr (istopcounter + 4), EDX

Setthreadpriority (getcurrentthread (), dwoldthreadp );
Setpriorityclass (getcurrentprocess (), dwoldprocessp );

Return (INT) (istopcounter-istartcounter)/62500 );
}

Previously, we used API functions for latency. If we know the CPU operating frequency and use loops, we can also get high-precision latency.

Int _ cpu_freq = 0; // define a global variable to save the CPU frequency (MHz)

Void cpudelayus (_ int64 US) // uses the cycle and CPU frequency delay, parameter: microsecond
{
_ Int64 icounter, istopcounter;

ASM rdtsc
ASM mov dword ptr icounter, eax
ASM mov dword ptr (icounter + 4), EDX

Istopcounter = icounter + US * _ cpu_freq;

While (istopcounter-icounter> 0)
{
ASM rdtsc
ASM mov dword ptr icounter, eax
ASM mov dword ptr (icounter + 4), EDX
}
}

Void testdelay (void)
{
_ Cpu_freq = cpu_frequency (); // use the CPU frequency to initialize the timer.
Cpudelayus (1000000); // delay 1 second
}

Summary:
Whether it is the delayus function in the previous program or the cpudelayus function, the foundation is actually the API function queryperformancecounter.
If you think that the precision is not enough, you can test the CPU frequency for a longer time delay, but after my test, 1/16 seconds is enough, you can measure the CPU working frequency with higher precision.
The delayus and cpudelayus functions can be used to implement high-precision (microsecond-level) latency in the program.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.