在Pentium的指令系统中有一条指令可以获得CPU内部64位计数器的值,我们可以通过代码两次获取该计数器的值而获得程序或代码运行的时钟周期数,进而通过你的cpu的频率算出一个时钟周期的时间,从而算出程序运行的确切时间。
我们通过指令TDSIC来获得cpu内部计数器的值,指令TDSIC返回值放在EDX:EAX中,其中EDX中存放64位寄存器中高32位的值,EAX存放第32位的值.
#include <iostream>
using namespace std;
int f()
{
for(int i= 0;i<10000;i++ )
for(int i= 0;i<10000;i++ ) ;
return 1;
}
int main()
{
long HighStart,LowStart,HighEnd,LowEnd;
//获取代码运行开始时cpu内部计数器的值
__asm
{
RDTSC
mov HighStart,edx
mov LowStart,eax
}
//————————
// int a=f(),b=a;//测试代码,b得到a的值是直接拿存储单元中拿算好的值呢,还是调用f()函数重新计算的值?这样时间就会有很大差别
int c,d;c=d=f();//与上一句对比
//————————
//获取代码结束时cpu内部计数器的值,并减去初值
__asm
{
RDTSC
mov HighEnd,edx
mov LowEnd,eax
}
__int64 timer1 =(HighEnd << 32)+LowEnd;
__int64 timer2 =(HighStart << 32)+LowStart;
printf(“%I64d\n”,timer1-timer2);
return 0;
}
结论:此程序在VC下编译通过,DEV-C和C-FREE都报错,且随着多次运行相同程序,会看到时间减少,说明应该有预处理作用
故对比效果不明显,但是给我的感觉,那两行测试代码第二行要快一些(实际结果也是这样,但是觉得这个结论有点草率),哪位大牛帮忙分析一下,对于上面第一行测试代码,会不会计算两次呢?
为什么会有这种测试念头,来自于PKU1061(不信的可以拿下面的代码去提交测试),两份代码只有一点点差别,一个TLE,一个AC,由此引发上面的测试~
#include <iostream>//AC
using namespace std;
__int64 xx,yy;
__int64 gcd(__int64 a,__int64 b)
{
if(b==0){ xx=1;yy=0; return a;}
int ans,tmp;
ans=gcd(b,a%b);tmp=xx;
xx=yy;yy=tmp-a/b*yy;
return ans;
}
int main()
{
__int64 x,y,m,n,l;
while(scanf(“%I64d%I64d%I64d%I64d%I64d”,&x,&y,&m,&n,&l)!=EOF)
{
__int64 ans,d;
ans=d=gcd(n-m,l);//差别在这
ans=(x-y)/ans*xx;
if(ans<0)while(ans<0)ans+=l;
else ans%=l;
if((x-y)%d==0)printf(“%I64d\n”,ans);
else printf(“Impossible\n”);
}
return 0;
}
————————————————————–
#include <iostream>//TLE
using namespace std;
__int64 xx,yy;
__int64 gcd(__int64 a,__int64 b)
{
if(b==0){ xx=1;yy=0; return a;}
int ans,tmp;
ans=gcd(b,a%b);tmp=xx;
xx=yy;yy=tmp-a/b*yy;
return ans;
}
int main()
{
__int64 x,y,m,n,l;
while(scanf(“%I64d%I64d%I64d%I64d%I64d”,&x,&y,&m,&n,&l)!=EOF)
{
__int64 ans=gcd(n-m,l),d=ans;//超时
ans=(x-y)/ans*xx;
if(ans<0)while(ans<0)ans+=l;
else ans%=l;
if((x-y)%d==0)printf(“%I64d\n”,ans);
else printf(“Impossible\n”);
}
return 0;
}