C ++中的确切睡眠时间 [英] Exact Sleep time in C++

查看:234
本文介绍了C ++中的确切睡眠时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在C ++中使用Sleep()时,我尝试测量确切的"睡眠时间.

所以,我使用了这段代码

I try to measure the ''exact'' sleep time when I use Sleep() in C++.

So, I used this code

#include <stdio.h>
#include <intrin.h>
#include <windows.h>
#include <iostream>
using namespace std;

unsigned __int64 testSleepExactTime(int relax);
unsigned __int64 getFreqFrom__rdtsc();

int main()
{
	unsigned int relax = 0;
	unsigned __int64 freq = 0;
	freq = getFreqFrom__rdtsc();
	cout <<"Input Relax time (millisec): ";
	cin >> relax;
	cout <<"relax Time : " << relax * 1000<<" Micro Sec."<<endl;
	cout <<"System frequency : "<<freq<<" Ticks per sec."<<endl;
	for(int i = 0;i<10;i++)
		cout <<"Exact relax time : " << testSleepExactTime(relax)*1000000/freq <<" Micro Sec."<< endl;
	for(int i = 0;i<10;i++)
		cout <<"Exact relax time(Double) : " << ((double)testSleepExactTime(relax))*1000000/freq <<" Micro Sec."<< endl;

	system("pause");
	return 0;
}
unsigned __int64 testSleepExactTime(int relax)
{
	unsigned __int64 start = 0;
	unsigned __int64 stop = 0;
	start = __rdtsc();
	Sleep(relax);
	stop = __rdtsc();
	return stop - start;
}
unsigned __int64 getFreqFrom__rdtsc()
{
	 unsigned __int64 start = 0;
	 unsigned __int64 stop = 0;
	 start = __rdtsc();
     Sleep(1000);
	 stop = __rdtsc();
	return stop-start;
}



当我输入1毫秒时,恢复为10000微秒
当我输入1000毫秒时,恢复为995000微秒

为什么当我使用1毫秒时,结果似乎不正确?

注意:
使用MSVC ++ 2010作为工具
基于Windows7
CPU i3 3.07GHz
PS.我不使用"QueryPerformanceFrequency()",因为它每秒返回约290万滴答.



when I input 1 millisecond, it resuted 10000 Microsecond
when I input 1000 millisecond, it resuted 995000 Microsecond

why when I use 1 millisecond that result seem incorrect?

note:
Using MSVC++2010 as tool
Base on Windows7
CPU i3 3.07GHz
PS. I''m not using ''QueryPerformanceFrequency()'' because it returns ~2.9m ticks per sec.

推荐答案

通常,当您尝试睡眠1毫秒时,由于CPU上的时钟分辨率,CPU睡眠约20-25毫秒.如果您使用Google"CPU时钟分辨率",则可能会找到更详细的说明.
Generally, when you try to sleep for 1 millisecond, the cpu sleeps for about 20-25 milliseconds due to the resolution of the clock on the CPU. If you google "cpu clock resolution" you''ll probably find more in-depth descriptions of what''s going on.


Sleep()接受一个参数,指定之前的毫秒数返回.让我们称该参数为" x "

Windows中的Sleep()(或任何其他形式的超时)不能保证您将完全在 x毫秒内恢复一次.它甚至不保证您将在"x"毫秒左右的任何时间恢复.这就是为什么.

您的进程(线程)只是PC中运行的多个进程/线程之一.打开任务管理器,然后查看进程"选项卡.单击查看"菜单,然后添加线程"和基本优先级"项.现在看看清单.

您的进程正在与PC中运行的每个进程中的每个线程争夺计算资源.查看基本优先级"列,您将看到列出了许多比您具有更高优先级的进程.如果他们需要CPU,这些都将使您无所适从.列出了许多与您具有相同优先级的进程.您将轮流执行这些过程.

因此,当Sleep()完成后,您的进程(线程)将再次被允许与其他进程竞争以引起CPU的注意.您不能保证先得到它.

总结一下:

1)正如其他人指出的那样,时钟分辨率的精度并不完全是1毫秒,因此您的Sleep()不会在精确地" x"毫秒内完成,而是会在 "x"毫秒后.

2)一旦时间过去,并且您的进程(线程)可以再次运行,它就必须与PC内当时正在发生的其他一切竞争,并且可能不得不等待轮到恢复执行.

以及您问题中的其他问题:

您计算freq的算法是有缺陷的,因为它依靠Sleep(1000)来校准值,并且正如我已经证明的那样,Sleep()不能用于此目的,并且本质上是不精确的.
Sleep() takes an argument specifying the number of milliseconds before returning. Let''s call that argument "x"

Sleep() (or any other form of timeout) in Windows does not guarantee that you will resume in exactly ''x'' milliseconds. It does not even guarantee that you will resume in anywhere near ''x'' milliseconds. Here''s why.

Your process (thread) is just one of a number of processes / threads running in your PC. Open Task Manager and look at the processes tab. Click the View menu and add the "Threads" and "Base Priority" items. Now look at the list.

Your process is competing for compute resources with every thread inside every process running in your PC. Look at the Base Priority column and you''ll see that there are many processes listed as having a higher priority than yours. These will all prempt you if they need the cpu. There are a number of processes listed as having the same priority as yours. You will take turns with these processes.

So, when your Sleep() is finished, your process (thread) is once again allowed to compete with these other processes for the cpu''s attention. You are not guaranteed to get it first.

To summarize:

1) as others have pointed out to you, the clock resolution is not exactly at 1 millisecond granularity so your Sleep() will not complete in exactly ''x'' milliseconds, but rather will complete sometime after ''x'' milliseconds have elapsed.

2) once the time has elapsed and your process (thread) is eligible to run again, it has to compete with everything else that is happening inside your PC at that moment and may have to wait its turn to resume execution.

And to your other issue in your question:

Your algorithm for figuring out freq is flawed because it relies on Sleep(1000) to calibrate the value and, as I''ve demonstrated, Sleep() cannot be used for this purpose and is inherently imprecise.


回复:QueryPeroformanceFrequency():

阅读Microsoft的描述和有关它的社区评论".

QueryPerformanceFrequency() [
考虑性能计数器是否实际上是cpu循环速度.然后,当您切换为电池电源时,数字会改变吗?当然,您的处理器芯片速度确实可以. 涡轮增压"模式怎么样?如果cpu循环速度像现代芯片中那样可变,并且在某些情况下,高精度计时器将毫无用处.

Microsoft的文档明确指出:
Re: QueryPeroformanceFrequency():

Read Microsoft''s description and the "community comments" on it.

QueryPerformanceFrequency()[^]

As one person noted, you are querying the frequency of the timer, not the frequency of the cpu processor. So regardless of what your CPU Chip speed is, this is a different "frequency".

Consider if the performance counter was, in fact, the cpu cycle speed. Then would the number change when you switched to battery power? Certainly your processor chip speed does. How about "turbo boost" mode? If the cpu cycle speed were variable as it is in modern chips and under certain circumstances, the high percision timer would be useless.

Microsoft''s documentation clearly states :
报价:

系统运行时频率无法更改.

The frequency cannot change while the system is running.

表示它没有改变.跟随cpu芯片时钟速度的起伏.

which implies that it does not follow the ups and downs of the cpu chip clock speed.


这篇关于C ++中的确切睡眠时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆