程序运行怎么这么快呢?毛了

yuriarthas 2011-08-20 04:40:48
自己写了个测试线段的函数,测试了一下正确性。感觉上是正确的。然后我觉得我写的比较烂,可能效率很低,于是想做个测试。结果,重复运行999999999次才运行了不到一秒。。。999,999,999是十亿次,我的CPU是i5-480的,主频是2.66G,为什么运行十亿次才不到1秒呢?

以下是程序,向各位大牛请教这是怎么回事。。。是不是我的函数没有真正运行啊
函数很长,很乱。。。不过函数本身不是问题,我只是想知道为什么程序运行这么快。。。
环境VS2010,Relase,MT,全程序优化

#include<Windows.h>
#include<stdio.h>
#include<time.h>

class Line
{
public:
static bool SegmentSegmentCross(Line &s1,Line &s2) ;
public:
POINT p1 ;
POINT p2 ;
} ;

int main()
{
Line s1,s2 ;
s1.p1.x=30,s1.p1.y=30 ;
s1.p2.x=30,s1.p2.y=100 ;

s2.p1.x=40 ;s2.p1.y=40 ;
s2.p2.x=25,s2.p2.y=400 ;
printf("s1.p1.x=%d,s1.p1.y=%d\ns1.p2.x=%d,s1.p2.y=%d\ns2.p1.x=%d,s2.p1.y=%d\ns2.p2.x=%d,s2.p2.y=%d\n",
s1.p1.x ,s1.p1.y,s1.p2.x ,s1.p2.y,s2.p1.x,s2.p1.y,s2.p2.x,s2.p2.y) ;

printf("%d\n\n",Line::SegmentSegmentCross(s1,s2) );
long time=clock() ;

for(unsigned __int64 i=0;i<999999999;i++)
{
Line::SegmentSegmentCross(s1,s2) ;
}

printf("999999999次花费时间:%lfs\n",(double)(-time+clock())/1000) ;
return 0 ;
}

bool Line::SegmentSegmentCross(Line &s1,Line &s2)
{
int s1_x=s1.p1.x-s1.p2.x ;
int s1_y=s1.p1.y-s1.p2.y ;
int s2_x=s2.p1.x-s2.p2.x ;
int s2_y=s2.p1.y-s2.p2.y ;
//printf("s1_x=%d,s1_y=%d,s2_x=%d,s2_y=%d\n",s1_x,s1_y,s2_x,s2_y) ;

if(s1_x!=0 && s2_x!=0) //k1、k2都存在
{
//printf("k1、k2都存在\n") ;
double k1= (double)s1_y / (double)s1_x ;
double k2= (double)s2_y / (double)s2_x ;

double b1=s1.p1.y-s1_y/s1_x*s1.p1.x ;
double b2=s2.p1.y-s2_y/s2_x*s2.p1.x ;

if(k1>k2-0.000001 && k1<k2+0.000001)
{
//平行
//printf("平行\n") ;
if(s1.p1.y>k2*s1.p1.x+b2-0.000001 && s1.p1.y<k2*s1.p1.x+b2+0.000001 ) // if(s1.p1.y==k2*s1.p1.x+b2)
return 1 ;
else return 0 ;
}
//printf("不平行\n") ;
double x=(b2-b1) / (k1 - k2) ;
double y=k1*x+b1 ;
//printf("k1=%lf,b1=%lf,k2=%lf,b2=%lf\n(x,y)=(%lf,%lf)\n",k1,b1,k2,b2,x,y) ;

double ymax,ymin ;
ymax=max(s1.p1.y,s1.p2.y) ;
ymin=min(s1.p1.y,s1.p2.y) ;
if(y>ymax+0.000001 || y<ymin-0.000001)
return 0 ;
ymax=max(s2.p1.y,s2.p2.y) ;
ymin=min(s2.p1.y,s2.p2.y) ;
if(y>ymax+0.000001 || y<ymin-0.000001)
return 0 ;
return 1 ;
}
else
{
//printf("至少有一条直线k不存在(至少有一条直线垂直)\n") ;
if(s1_x==0)
{
if(s2_x==0) // s1_x==0 and s2_x==0
{
//printf("都垂直\n") ;
if(s1.p1.y==s2.p1.y)
return 1 ;
else return 0 ;
}
else // s1_x==0 and s2_x!=0
{
double xmax,xmin ;
xmax=max(s2.p1.x,s2.p2.x) ;
xmin=min(s2.p1.x,s2.p2.x) ;
if(s1.p1.x<xmax+0.000001 && s1.p1.x>xmin-0.000001)
{ //以下代码考虑的是,x轴上有投影相交,y轴不想交
double k2=(double)s2_y/(double)s2_x ;
double b2=s2.p1.y-k2*s2.p1.x ;
double y=k2*s1.p1.x+b2 ;
double ymin,ymax ;
ymax=max(s1.p1.y,s1.p2.y) ;
ymin=min(s1.p1.y,s1.p2.y) ;
if(y<ymax+0.000001 && y>ymin-0.000001)
return 1 ;
else return 0 ;
}
else return 0 ;
}
}
else //s1_x!=0
{
double xmax,xmin ;
xmax=max(s1.p1.x,s1.p2.x) ;
xmin=min(s1.p1.x,s1.p2.x) ;
if(s2.p1.x<xmax+0.000001 && s2.p1.x>xmin-0.000001)
{
double k1=(double)s1_y/(double)s1_x ;
double b1=s1.p1.y-k1*s1.p1.x ;
double y=k1*s2.p1.x+b1 ;
double ymin,ymax ;
ymax=max(s2.p1.y,s2.p2.y) ;
ymin=min(s2.p1.y,s2.p2.y) ;
if(y<ymax+0.000001 && y>ymin-0.000001)
return 1 ;
else return 0 ;
}
else return 0 ;
}
}
}

...全文
233 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuriarthas 2011-08-21
  • 打赏
  • 举报
回复
我是楼主 我用单步调试开始执行程序。到了for循环的时候,对着反汇编单步调试。反汇编的代码很多的,单步走的话大约要走30步。。。具体多少忘了,现在不在自己的机器旁边,没法测试。2.66G主频,算十亿*30条指令,需要很长时间吧,毕竟指令里面不只是mov或者jmp这种指令。。

楼上有人说36秒的或者更长时间的我觉得还靠谱,我这个1秒不到,真蛋疼,快是好事,可是离谱了就毛了,感觉有点象动车。。。

看上面的回复好象没有时间和我的差不多的。。。难道说真和15楼说的那样,这是无意义的代码?但是若真无意义的话,应该是0.0000000s才对啊。

另外i5-480这种CPU真算不上好,现在也就算个一般吧。。。双核四线程2.66G主频算这种单线程的程序恐怕和几年前的CPU相比都没什么优势。

另外,debug下运行9秒左右。。有没有大牛能解释一下啊
pathuang68 2011-08-21
  • 打赏
  • 举报
回复
楼主试试下面的程序,一共计算了100亿亿次加法,在release的方式下运行的时间几乎为0ms,CPU也几乎无任何变化:

#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
long long sum = 0;

for(int i = 0; i < 999999999; ++i)
{
for(int j = 0; j < 999999999; ++j)
{
sum += j;
}
sum = 0;
}
return 0;
}


计算机真的有这么快吗?当然不是,完全是编译器的优化在“骗”咱们。我的机器是i5 cpu@2.4GHz。
CCSOY 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 xunxun1982 的回复:]

lz在XY
鉴定完毕
[/Quote]
同意
pathuang68 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 yuriarthas 的回复:]

我是楼主 我用单步调试开始执行程序。到了for循环的时候,对着反汇编单步调试。反汇编的代码很多的,单步走的话大约要走30步。。。具体多少忘了,现在不在自己的机器旁边,没法测试。2.66G主频,算十亿*30条指令,需要很长时间吧,毕竟指令里面不只是mov或者jmp这种指令。。

楼上有人说36秒的或者更长时间的我觉得还靠谱,我这个1秒不到,真蛋疼,快是好事,可是离谱了就毛了,感觉有点象动车。。……
[/Quote]

楼主写的这种计算代码,严格地说和是否多核关系并不大。
吾子墨鸿 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 matrixcl 的回复:]
楼主用的release版本。

release版本中,编译器会将无意义的代码优化掉。同一个函数调用10亿次不保存结果,对编译器而言就是无意义的代码。

运行加个断点,打开汇编窗口就明白了
[/Quote]
正解+1
yuriarthas 2011-08-21
  • 打赏
  • 举报
回复
怎么就沉了。。。顶起来
matrixcl 2011-08-20
  • 打赏
  • 举报
回复
汇编窗口中:

debug:

int a1 = 0;
013926FD mov dword ptr [ebp-14h],0

for (int i = 0; i<100000; i++)
01392704 mov dword ptr [i],0
0139270B jmp main+56h (1392716h)
0139270D mov eax,dword ptr [i]
01392710 add eax,1
01392713 mov dword ptr [i],eax
01392716 cmp dword ptr [i],186A0h
0139271D jge main+68h (1392728h)
{
a1 = 1;
0139271F mov dword ptr [ebp-14h],1
}
01392726 jmp main+4Dh (139270Dh)
printf("%d\n", a1);
01392728 mov esi,esp
0139272A mov eax,dword ptr [ebp-14h]
0139272D push eax
0139272E push offset string "%d\n" (13A0A48h)
01392733 call dword ptr [__imp__printf (13A5714h)]
01392739 add esp,8
0139273C cmp esi,esp
0139273E call @ILT+1165(__RTC_CheckEsp) (1391492h)



release:

int a1 = 0;

for (int i = 0; i<100000; i++)
{
a1 = 1;
}
printf("%d\n", a1);
010E10A2 mov ebx,dword ptr [__imp__printf (10E4140h)]
010E10A8 push 1
010E10AA push offset string "%d\n" (10E41ECh)
010E10AF call ebx
010E10B1 add esp,8
matrixcl 2011-08-20
  • 打赏
  • 举报
回复
楼主用的release版本。

release版本中,编译器会将无意义的代码优化掉。同一个函数调用10亿次不保存结果,对编译器而言就是无意义的代码。

运行加个断点,打开汇编窗口就明白了
jernymy 2011-08-20
  • 打赏
  • 举报
回复
楼主的机器比较给力
xunxun 2011-08-20
  • 打赏
  • 举报
回复
lz在XY
鉴定完毕
pwxcomer 2011-08-20
  • 打赏
  • 举报
回复
999999999次花费时间:79.563000s
Nosky100 2011-08-20
  • 打赏
  • 举报
回复
简易版3DMark诞生了。
猫xiaowai 2011-08-20
  • 打赏
  • 举报
回复
悲剧的机器花了307.688000S
QQ515311445 2011-08-20
  • 打赏
  • 举报
回复
Microsoft Windows XP Professional Service Pack 3
Pentium(R) D CPU 3.00GHz 896MB的内存
148.157000s
贪食蛇男 2011-08-20
  • 打赏
  • 举报
回复
999999999次花费时间:36.312000s
贪食蛇男 2011-08-20
  • 打赏
  • 举报
回复
机器好呗。我奔腾双核哭了
yanwufengxie 2011-08-20
  • 打赏
  • 举报
回复
编译器会对代码高度优化,要知道为什么这么快要看反汇编,另测试时间用queryperformancecount。
低头路过 2011-08-20
  • 打赏
  • 举报
回复
楼上的回复让我非常egg pain。。。
jackyjkchen 2011-08-20
  • 打赏
  • 举报
回复
优化过后,可能你许多循环都没执行
ningto.com 2011-08-20
  • 打赏
  • 举报
回复
拜托你运行完没有啊, 我这里花了105秒
加载更多回复(5)

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧