如何在代码中计算时钟周期数


title: 如何在代码中计算时钟周期数
date: 2020-01-02 20:33:57
description: 如何在代码中计算时钟周期数

如何在代码中计算代码执行的时钟周期数

 有的时候,需要在代码中获取代码运行的时钟周期数。那么,怎么获取到某段代码在运行时的时钟周期数呢?

通过获取程序运行时间

 在代码中直接计算一个程序的时钟周期是不容易的。但是计算一个程序的执行时间却是比较容易的。编程语言和操作系统都提供有相关的封装好的接口,可以很方便地调用来得到程序的运行时间。这方面的参考资料很多,我就不去介绍了。

 如何获取程序的执行时间? Linux环境 || Windows环境

 下面来介绍一下怎么通过获取的程序执行时间来得到时钟周期数。
 CPU时钟周期:通常为节拍脉冲或T周期,即主频的倒数,它是CPU中最小的时间单位,每个动作至少需要一个时钟周期。而主频又与与具体的时间有关。CPU的主频表示每秒进行的时钟周期数。那么运行时间与时钟周期数有如下的计算方式:

时钟周期数计算

 根据获取的运行时间和CPU的主频可以计算出程序的时钟周期数。

直接计算时钟周期数

 也有直接计算时钟周期数的方法。为了给计时测量提供更高的准确度,很多处理器还包含一个运行在始终周期级别的计时器,它是一个特殊的寄存器,每个时钟周期它都会自动加1。这个周期计数器呢,是一个64位无符号数,直观理解,就是如果你的处理器是1GHz的,那么需要570年,它才会从2的64次方绕回到0,所以你大可不必考虑溢出的问题。但是这种方法是依赖于硬件的。首先,并不是每种处理器都有这样的寄存器的;其次,即使大多数都有,实现机制也不一样,因此,我们无法用统一的,与平台无关的接口来使用它们。于是就要使用汇编来处理。在这里给出一个C语言嵌入汇编的例程。

unsigned long long int begin,end,total=0;	
static __inline__ unsigned long long rdtsc(void)	 
{	 
	unsigned hi, lo; 	
	__asm__ __volatile__ ("rdtsc" : "=a"(lo),"=d"(hi));	 
	return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );	 
} 
 
int main(){   
	begin=rdtsc();   

	//这里调用要测试的函数   
	end=rdtsc();   
	total = end – begin; // total即為 cpu clock cycle 
} 

存在的问题

对于第一种方法

 对于先计时再计算时钟周期数,除开计时器本身可能存在的精度问题。另外,时间 = 周期数 / 频率,由于频率可能会变(比如我的笔记本的 CPU 通常半速运行在 800MHz,繁忙的时候全速运行在 1.6GHz),那么测得的时间也就不准确了。计算的时钟周期就不准。

对于第二种方法

原文链接

 在多核时代,RDTSC 指令的准确度大大削弱了,原因有三:

  • 不能保证同一块主板上每个核的 TSC 是同步的;
  • CPU 的时钟频率可能变化,例如笔记本电脑的节能功能;
  • 乱序执行导致 RDTSC 测得的周期数不准,这个问题从 Pentium Pro 时代就存在。

 在多核下,这两次执行可能会在两个CPU上发生,而这两个CPU的计数器的初值不一定相同(由于完成上电复位的准确时机不同),(有办法同步,见如何同步),那么就导致结果包含了这个误差,这个误差可正可负,取决于先执行的那块CPU 的时钟计数器是超前还是落后。

 乱序执行这个问题比较简单,但意义深远。在现代 CPU 的复杂架构下,测量几条或几十条指令的耗时是无意义的,因为观测本身会干扰 CPU 的执行(cache, 流水线, 多发射,乱序, 猜测)。要么我们以更宏观的指标来标示性能;要么用专门的手段来减小对观测结果的影响。

 当然,无论怎样,都不可能测得一个程序的准确时钟周期数。但是在允许一定误差存在的条件下,这些方法是有效的,根据场景合理的选择需要的方法。

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值