惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy & Cybersecurity Law Blog
V
V2EX
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Register - Security
The Register - Security
MongoDB | Blog
MongoDB | Blog
P
Privacy International News Feed
The Last Watchdog
The Last Watchdog
Security Archives - TechRepublic
Security Archives - TechRepublic
美团技术团队
Stack Overflow Blog
Stack Overflow Blog
博客园 - 司徒正美
博客园 - 三生石上(FineUI控件)
V
Visual Studio Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
K
Kaspersky official blog
S
Secure Thoughts
T
Tenable Blog
Security Latest
Security Latest
The Cloudflare Blog
S
Security @ Cisco Blogs
H
Heimdal Security Blog
aimingoo的专栏
aimingoo的专栏
TaoSecurity Blog
TaoSecurity Blog
Blog — PlanetScale
Blog — PlanetScale
Microsoft Security Blog
Microsoft Security Blog
Schneier on Security
Schneier on Security
Webroot Blog
Webroot Blog
G
Google Developers Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Scott Helme
Scott Helme
IT之家
IT之家
Latest news
Latest news
The Hacker News
The Hacker News
C
Check Point Blog
T
The Exploit Database - CXSecurity.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More
腾讯CDC
C
CERT Recently Published Vulnerability Notes
NISL@THU
NISL@THU
N
News | PayPal Newsroom
Forbes - Security
Forbes - Security
P
Palo Alto Networks Blog
S
Security Affairs
S
Securelist
Google Online Security Blog
Google Online Security Blog
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
C
Cybersecurity and Infrastructure Security Agency CISA
A
About on SuperTechFans

博客园 - 小张.NET

模仿写了一个摸鱼应用解决原作者的问题 第一屏不显示懒加载的图片内容,这个方法可以搞定 C#多线程中访问winform控件 (解决Winform 对象当前正在其他地方使用) 变化的科技感十足的网站,推荐 新年有感 修改 TeamViewer ID 的方法 VS2017离线安装包[百度云盘](收藏了) 老子今天不加班,程序员也需要自由 改变Eclipse 中代码字体大小 去除 VS.Net 2003 项目的 VSS 息的脚本 字符串截取固定长度的方法(C#) 两种彻底删除VIEWSTATE的方法 - 小张.NET - 博客园 对路径XXX的访问被拒绝(文件操作权限)的解决方法 安装VS2005 SP1之后无法更改或卸载VS2005的处理方法 VS2005的隐藏快捷键 vs2005的快捷键 反编译工具Reflector下载(集成两个常用.net插件,FileGenerator和FileDisassembler) 强大的.NET反编译工具Reflector及插件 程序员,你离坐牢还有多远 - 小张.NET - 博客园
获取高精度时间注意事项 (QueryPerformanceCounter , QueryPerformanceFrequency)
小张.NET · 2019-03-26 · via 博客园 - 小张.NET

花了很长时间才得到的经验,与大家分享。

1. RDTSC - 粒度: 纳秒级 不推荐
优势: 几乎是能够获得最细粒度的计数器
抛弃理由:

A) 定义模糊
- 曾经据说是处理器的cycle counter,但是后来似乎又不是了。
有的机器上每秒的TSC增长值等于CPU频率,有的却是一个不对应任何配置的数。到底是什么,Intel也没解释清楚。

B) 不准确
- 这是最重大的缺陷。再细的粒度,不准的话也没用,至少不能当时间用。
在有的CPU上,特别是支持变频技术的笔记本CPU上,TSC增长值会随着CPU的频率改变。忙的时候跑得快,闲得时候跑得慢。

2. QueryPerformanceCounter - 粒度: 1~100微秒级 不推荐
优势: 尽管比RDTSC粒度稍低,但是不存在RDTSC在变频CPU上的问题。
知道这个API的人估计都倾向于用这个,因为M$对这个API给出了比较明确的定义,就是每秒钟某个计数器增长的数值。
抛弃理由: 还是不准确

尽管没有源代码,但是从M$的帮助文档和知识库可以了解到,PerformanceCounter是依赖于主板上与PCI设备有关联的硬件。这就意味着,PerformanceCounter的结果还是会受到硬件频率,特别是总线频率的影响。

事实上,我在EeePC上测试的时候就发现,系统采用节能模式的时候PerformanceCounter出来的结果老是偏慢很多,超频模式的时候又偏快,而且用电池和接电源的时候效果还不一样!

3. timeGetTime - 粒度: 毫秒级 推荐
尽管粒度进一步降低,但是其无与伦比的优势就是,准确。
在任何机器上返回的都是当前系统的启动时间,精确到1毫秒。

使用注意事项:

A) 在NT系统上(据说)默认精度为10ms,但是可以用timeBeginPeriod来降低到1ms
B) 返回的是一个32位整数,所以要注意大约每49.71天会出现归零(不像前两个是64位数,要几百年才会归零)。
---------------------------------------------- 

实际上timeGetTime以及GetTickCount也是由QueryPerformanceCounter/QueryPerformanceFrequency得到的,因为做了除以频率的操作,所以得到的数值比较客观,准确

明显不是的。

我的代码就是用QueryPerformanceCounter / QueryPerformanceFrequency得到实际经过的时间。

测试方法为: 调用时间API, Sleep 500ms, 再调用时间API, 不停的循环。

用 两次timeGetTime的差值得到经过的毫秒数 (简称 Tick)
与 两次QueryPerformanceCounter的差值/QueryPerformanceFrequency得到经过的毫秒数 (简称 Counter)

比较发现:

在EeePC 正常模式下: Tick: 500ms, Counter: 500ms
在超频模式下: Tick: 500ms, Counter: 535ms
在节能模式下: Tick: 500ms, Counter: 260ms

可见用多媒体时钟timeGetTime始终是稳定的,但是PerformanceCounter就不行了。
---------------------------------------------- 

M$的有一个KB上提到芯片组Bug导致QueryPerformanceCounter有时候会往前跳几秒。描述原因的时候说是因为芯片组在PCI Bus上的Bug导致系统接受到奇怪的消息,系统为了保证稳定就会往PerformanceCounter上加几秒钟。从这个描述上就可以看出,PerformanceCounter是以PCI Bus的某个硬件作为基础的。

事实上,有的人说PerformanceCounter是系统接受的IRQ#0的计数器,但是还有一种说法是,在有的系统上PerformanceCounter会使用CPU的TSC...

总之,Performance Counter也不是一个可以100%靠得住的时间源。

要想你的代码在大量配置不同的机器上不出问题,目前只有依赖timerGetTime这个多媒体时钟。
---------------------------------------------- 

大概瞅了一下intel manual,vol3b (system programming guide B)里ch18第11和20节讲的是关于计时的
手册2b里RDTSC中除了说3b的18章外,还提到了3b的21章,这些你都仔细读过了之后得到上述关于RDTSC的结论的么?

er... 我的是经验,不是结论。靠读manual是不可能得到的,是我花了很长时间在很多机器上试验得到的结果。

有的机器上RDTSC的增幅是和频率一致的,但是多数是台式机,而且是老型号。
新的台式机和笔记本CPU的RDTSC的增幅明显不是频率,有说法是总线的主频。
Pentium M的TSC会随着speedstep变化;服务器的好像还挺稳定,但是我没有打开Linux内核的CPU Frequency Scaling,说不定打开了以后也会出现这个现象。

在多CPU下,每一个CPU的RDTSC是独立的;SMP下运行的线程可能会被放到不同的CPU下运行,这意味着两次读TSC可能会出现后面比前面小的情况,所以最好还要SetThreadAffinity,绑定在一块CPU上。

总之TSC用起来也很麻烦,而且太底层,很难在不同的配置下兼容。这个东西用来做单个机器的Profiling不错(本来就是为了这个目的),但是如果当成时间源的话就差了。
---------------------------------------------- 

我建议吧,和硬件有关的东西还是直接看官方的manual,贷是人家设计的,手册不可能还没你的经验靠谱
下面这段是vol 3b ch18.20中最开头的部分,建议你在自己已经做过之前,不要轻易下“靠读manual是不可能得到的”这种结论
The count of cycles, also known as clockticks, forms a the basis for measuring how 
long a program takes to execute. Clockticks are also used as part of efficiency ratios 
like cycles per instruction (CPI). Processor clocks may stop ticking under circum-
stances like the following:
? The processor is halted when there is nothing for the CPU to do. For example, the 
processor may halt to save power while the computer is servicing an I/O request. 
When Intel Hyper-Threading Technology is enabled, both logical processors must 
be halted for performance-monitoring counters to be powered down.
? The processor is asleep as a result of being halted or because of a power-
management scheme. There are different levels of sleep. In the some deep sleep 
levels, the time-stamp counter stops counting.
In addition, processor core clocks may undergo transitions at different ratios relative 
to the processor’s bus clock frequency. Some of the situations that can cause 
processor core clock to undergo frequency transitions include:
? TM2 transitions
? Enhanced Intel SpeedStep Technology transitions (P-state transitions)
----------------------------------------------