user-0 提问: 请问t1和t2函数的哪个运行速度更快呢？？这个自己有点纠结

回复:
user: user-1
content: 这个应该是 先计算B 的要快一些，因为A可以把B 的运算拿来套用。

user: user-2
content: 引用 38 楼 lm_whales 的回复:[quote=引用 31 楼 unituniverse2 的回复:] [quote=引用 30 楼 lm_whales 的回复:] [quote=引用 27 楼 unituniverse2 的回复:] 这次是release模式，开了快速模式编译，同样关了动态超频，使用低频测试：  #define A 10000000 #define B 100 的时候 1891 2714  #define A 1000000 #define B 1000 的时候 1836 2540  #define A 10000000 #define B 1000 的时候 17245 26355 看来你只看了最后一贴。。。我说的是对于同样的代码，按快速模式优化的程序比按最小模式优化的代码执行起来反而更慢[/quote] #include<time.h> #include<stdio.h>  #define A 10000000  #define B 1000  int a[A],b[B];    void t1(){ int j; for(j=0;j<B;j++) {   b[j] += A; }   }  void t2(){ int i; for(i=0;i<A;i++) {   a[i] += B; } }    int main() { 	clock_t t =clock();     t1(); 	printf("t1= %d\n",clock()-t); 	t=clock(); 	t2(); 	printf("t2= %d\n",clock()-t); 	getchar();  return 0; } Debug: t1= 0 t2= 109 Release 速度最快: t1= 0 t2= 31 Release 代码最小: t1= 0 t2= 47 你的电脑该淘汰了，太慢了点。 速度最快，比代码最小要快一点，不明显。 另外clock();计时精度也太低了点。  [/quote]  你有看到我说了降频测试的么，别说没注意。而且还得关了动态超频测试。这个频率是多少我补充一下：1.1G 你这个例程我这里测试的结果： 最小模式优化： t1= 0 t2= 34 t3= 19489 t1= 0 t2= 20 t3= 19558 t1= 0 t2= 19 t3= 19662 t1= 0 t2= 19 t3= 19686 t1= 0 t2= 20 t3= 19501 t1= 0 t2= 19 t3= 19636 t1= 0 t2= 20 t3= 19702 t1= 0 t2= 19 t3= 19618  最快模式优化： t1= 0 t2= 34 t3= 19465 t1= 0 t2= 20 t3= 19334 t1= 0 t2= 19 t3= 19356 t1= 0 t2= 19 t3= 19461 t1= 0 t2= 20 t3= 19514 t1= 0 t2= 18 t3= 19251 t1= 0 t2= 19 t3= 19471 t1= 0 t2= 19 t3= 19386  还好意思说淘汰。别告诉我你的机器比这个频率还低。你还是用lz那个例子程序测吧，=0居然都给你报出来了。。。你这个例程就是故意做成有利于编译器优化的状态的，这样测当然能达到优化的预期目的，而且你这个0，完全不能证明你的处理器有多“快”。因为根据n你提供的t1函数，编译后得到如下汇编代码（我这里贴的是最小模式的）：  00EF1000  mov         eax,offset b (0EF3370h)   00EF1005  mov         ecx,dword ptr [eax]   00EF1007  add         ecx,989680h   00EF100D  mov         dword ptr [eax],ecx   00EF100F  add         eax,4   00EF1012  cmp         eax,offset a (0EF4310h)   00EF1017  jl          t1+5 (0EF1005h)   00EF1019  ret    989680h即是10000000，编译器并没有老实的做两层循环，而是直接把结果加到初始值上去了，因为你的程序里内层循环没有移动地址，编译器完全可以拆掉这个循环。真正执行的循环次数只有1000轮

user: user-3
content: 引用 27 楼 unituniverse2 的回复:这次是release模式，开了快速模式编译，同样关了动态超频，使用低频测试：  #define A 10000000 #define B 100 的时候 1891 2714  #define A 1000000 #define B 1000 的时候 1836 2540  #define A 10000000 #define B 1000 的时候 17245 26355  我就不明白了，按快速模式优化的程序怎么跑起来还会更慢。。。不知道什么情况。。。  比较的条件，结果就不同，不知道你有啥好郁闷的。 循环优化本来就不是那么容易的，你以为开了优化，就会加快多少了。  要知道，编译器是按照一定模式，进行优化的； 虽然多数情况下，优化的程序要好，但是永远做不到最好。  因为编译器，是人编写的。 人没有想到的，编译器就没有办法做到。  你的两个数组大小完全不一样，他们造成的影响，掩盖了代码优化的影响。  B是个小数组，安排在同一页面是没有问题的 最多也就在两个页面内 t1() 这段程序，除了，每个页面第一次访问，需要调页以外，整个循环期间，页面可以始终在内存中，不需要换页 当然要快得多，不管循环优化没有。  t2() 这段程序 9K多的页面，无论怎样优化； 换页总是难以避免的，怎么优化也不可能快起来。  至于高速缓存命中问题，确实也会拖累这段程序，不过影响应该没有那么大。 因为即使很小一块内存，也难免会有，不命中的时候，虽然几率更小。  PS: 循环优化，是针对同一种情况，为了减少跳转的影响，而做的努力。  比起高速缓存命中问题，解决的根本就是不痛不痒的问题  比起换页的影响，就更是云泥之别。  这怎么能在一起比较呢。

user: user-3
content: #include<time.h> #include<stdio.h> #include<windows.h>  #define A 10000000  #define B 1000  int a[A],b[B];    void t1(){ int j; for(j=0;j<B;j++) {   b[j] += A; }   }  void t2(){ int i; for(i=0;i<A;i++) {   a[i] += B; } }   #define test(fun) {clock_t t =clock(); fun();	printf("%s= %d\n",#fun,clock()-t); }  #define Test() {test(t1);test(t2);}    	             int main(){ 	Test(); 	Test(); 	Test(); 	Test(); 	Test(); 	Test(); 	Test(); 	Test(); 	getchar();  return 0; } Debug  t1= 0 t2= 94 t1= 0 t2= 93 t1= 0 t2= 110 t1= 0 t2= 93 t1= 0 t2= 79 t1= 0 t2= 78 t1= 0 t2= 78 t1= 0 t2= 62 Release 使大小最小化 (/O1) t1= 0 t2= 63 t1= 0 t2= 16 t1= 0 t2= 31 t1= 0 t2= 62 t1= 0 t2= 16 t1= 0 t2= 31 t1= 0 t2= 47 t1= 0 t2= 15 Release 使速度最大化 (/O2) t1= 0 t2= 47 t1= 0 t2= 16 t1= 0 t2= 31 t1= 0 t2= 15 t1= 0 t2= 32 t1= 0 t2= 15 t1= 0 t2= 32 t1= 0 t2= 15  PS : 首先，clock() 计时精度不够，其次，每次执行时间不一致。 然后使速度最大化，总比使大小最小化略快。 然后小内存操作要快。Release 比Debug 快  #include<time.h> #include<stdio.h> #include<windows.h>  #define A 10000000  #define B 1000  int a[A],b[B];    void t1(){ int i,j; for(j=0;j<B;j++)for(i=0;i<A;i++) {   b[j] ++; }   }  void t2(){ int i,j; for(i=0;i<A;i++)for(j=0;j<B;j++) {   a[i] ++; } }  void t3(){ int i,j; for(j=0;j<B;j++)for(i=0;i<A;i++) {   a[i] ++; } }   #define test(fun) {clock_t t =clock(); fun();	printf("%s= %d\n",#fun,clock()-t); }  #define Test() {test(t1);test(t2);test(t3);}    	             int main(){ 	Test(); 	Test(); 	Test(); 	Test(); 	Test(); 	Test(); 	Test(); 	Test(); 	getchar();  return 0; } Release，使速度最大化 (/O2) t1= 0 t2= 47 t3= 29063 t1= 0 t2= 31 t3= 25484 t1= 0 t2= 31 t3= 25391 t1= 0 t2= 15 t3= 25375 t1= 0 t2= 32 t3= 25546 t1= 0 t2= 32 t3= 25765 t1= 0 t2= 32 t3= 25578 t1= 0 t2= 31 t3= 25531 Release，使速度最大化 (/O2) t1= 0 t2= 46 t3= 30969 t1= 0 t2= 31 t3= 28422 t1= 0 t2= 47 t3= 28266 t1= 0 t2= 47 t3= 28547 t1= 0 t2= 31 t3= 28641 t1= 0 t2= 47 t3= 28437 t1= 0 t2= 32 t3= 28281 t1= 0 t2= 31 t3= 28000

user: user-3
content: 引用 31 楼 unituniverse2 的回复:[quote=引用 30 楼 lm_whales 的回复:] [quote=引用 27 楼 unituniverse2 的回复:] 这次是release模式，开了快速模式编译，同样关了动态超频，使用低频测试：  #define A 10000000 #define B 100 的时候 1891 2714  #define A 1000000 #define B 1000 的时候 1836 2540  #define A 10000000 #define B 1000 的时候 17245 26355 看来你只看了最后一贴。。。我说的是对于同样的代码，按快速模式优化的程序比按最小模式优化的代码执行起来反而更慢[/quote] #include<time.h> #include<stdio.h>  #define A 10000000  #define B 1000  int a[A],b[B];    void t1(){ int j; for(j=0;j<B;j++) {   b[j] += A; }   }  void t2(){ int i; for(i=0;i<A;i++) {   a[i] += B; } }    int main() { 	clock_t t =clock();     t1(); 	printf("t1= %d\n",clock()-t); 	t=clock(); 	t2(); 	printf("t2= %d\n",clock()-t); 	getchar();  return 0; } Debug: t1= 0 t2= 109 Release 速度最快: t1= 0 t2= 31 Release 代码最小: t1= 0 t2= 47 你的电脑该淘汰了，太慢了点。 速度最快，比代码最小要快一点，不明显。 另外clock();计时精度也太低了点。

user: user-3
content: 因为编译器，是人编写的。 人没有想到的，编译器就没有办法做到。  有些因素，编译器，不一定会考虑到。  编译器优化，只是对通常的代码，是那个样子的。 通常，   选择快速优化的比较快，通常程序代码比较长。   选择短小优化的比较慢，但是代码更短。  这只是一种取舍而已，并不是必然会快。 虽然90%以上的时候，快速优化编译的代码更快。  但这不是绝对的。

user: user-4
content: 引用 35 楼 unituniverse2 的回复:[quote=引用 33 楼 zhao4zhong1 的回复:] 使用电脑计时有时误差会很大，因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次，手动掐秒表计时可能更准确。 本来不想说的。。。受不了。。电脑时钟是由独立芯片控制的，即使死机这个时钟都照样继续走。一般程序的运行不会影响这个时钟的准确性 要说“有影响”倒是时钟取值函数本身的运行时开销。但是如果程序的计时算法设计到位的话（比如lz的程序，只是循环开始和结束各调用一次，纳秒级的调用开销和循环体秒级别的相比可以忽略不计了）。这个时间绝对比你手动掐表的更准[/quote] 两个M个N核CPU的机器，对准其时间，写一个while死循环程序，在一个机器上启动M×N个实例让CPU总负荷100%，持续1小时，观察两个机器的时钟差多少再说。

user: user-2
content: 引用 33 楼 zhao4zhong1 的回复:使用电脑计时有时误差会很大，因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次，手动掐秒表计时可能更准确。 本来不想说的。。。受不了。。电脑时钟是由独立芯片控制的，即使死机这个时钟都照样继续走。一般程序的运行不会影响这个时钟的准确性 要说“有影响”倒是时钟取值函数本身的运行时开销。但是如果程序的计时算法设计到位的话（比如lz的程序，只是循环开始和结束各调用一次，纳秒级的调用开销和循环体秒级别的相比可以忽略不计了）。这个时间绝对比你手动掐表的更准

user: user-5
content: 忍不住要说一句,闲的蛋疼

user: user-4
content: 使用电脑计时有时误差会很大，因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次，手动掐秒表计时可能更准确。

user: user-6
content: 楼主自己运行一次不就得了，看每一个函数运行需要多少时间，原理的话我觉得30楼说的挺有道理的

user: user-2
content: 引用 30 楼 lm_whales 的回复:[quote=引用 27 楼 unituniverse2 的回复:] 这次是release模式，开了快速模式编译，同样关了动态超频，使用低频测试：  #define A 10000000 #define B 100 的时候 1891 2714  #define A 1000000 #define B 1000 的时候 1836 2540  #define A 10000000 #define B 1000 的时候 17245 26355  我就不明白了，按快速模式优化的程序怎么跑起来还会更慢。。。不知道什么情况。。。  比较的条件，结果就不同，不知道你有啥好郁闷的。 循环优化本来就不是那么容易的，你以为开了优化，就会加快多少了。  要知道，编译器是按照一定模式，进行优化的； 虽然多数情况下，优化的程序要好，但是永远做不到最好。  因为编译器，是人编写的。 人没有想到的，编译器就没有办法做到。  你的两个数组大小完全不一样，他们造成的影响，掩盖了代码优化的影响。  B是个小数组，安排在同一页面是没有问题的 最多也就在两个页面内 t1() 这段程序，除了，每个页面第一次访问，需要调页以外，整个循环期间，页面可以始终在内存中，不需要换页 当然要快得多，不管循环优化没有。  t2() 这段程序 9K多的页面，无论怎样优化； 换页总是难以避免的，怎么优化也不可能快起来。  至于高速缓存命中问题，确实也会拖累这段程序，不过影响应该没有那么大。 因为即使很小一块内存，也难免会有，不命中的时候，虽然几率更小。  PS: 循环优化，是针对同一种情况，为了减少跳转的影响，而做的努力。  比起高速缓存命中问题，解决的根本就是不痛不痒的问题  比起换页的影响，就更是云泥之别。  这怎么能在一起比较呢。 [/quote] 看来你只看了最后一贴。。。我说的是对于同样的代码，按快速模式优化的程序比按最小模式优化的代码执行起来反而更慢

user: user-7
content: 引用 15 楼 user-9 的回复:猜够了  发运行截图   试试关闭所有优化， 然单独运行t1,t2。 估计相差不大。

user: user-7
content: 引用 13 楼 mujiok2003 的回复:等价代码， 显然t2更快（更少的工作，更好的局部性）。   #define A 10000000 #define B 1000 int a[A],b[B];  void t1(){ int j; for(j=0;j<B;j++) {   b[j]+ = A; }  } void t2(){ int i; for(i=0;i<A;i++) {   a[i] += B; } }  说反了， t1更快。

user: user-4
content: 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  使用电脑计时有时误差会很大，因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次，手动掐秒表计时可能更准确。

user: user-8
content: 运行一万遍自己看时间。。。

user: user-0
content: 引用 15 楼 user-9 的回复:猜够了  发运行截图  妙事上楼这位兄台更有说服力的赶脚。。。不过不同的机器运行时间应该不一样是吧？cpu处理时间不一样，不过应该不影响结果，也就是t1要快一点是吧。。

user: user-9
content: 猜够了  发运行截图

user: user-7
content: 引用 13 楼 mujiok2003 的回复:等价代码， 显然t2更快（更少的工作，更好的局部性）。   #define A 10000000 #define B 1000 int a[A],b[B];  void t1(){ int j; for(j=0;j<B;j++) {   b[j]+ = A; }  } void t2(){ int i; for(i=0;i<A;i++) {   a[i] += B; } }   忽略局部性。

user: user-7
content: 等价代码， 显然t2更快（更少的工作，更好的局部性）。   #define A 10000000 #define B 1000 int a[A],b[B];  void t1(){ int j; for(j=0;j<B;j++) {   b[j]+ = A; }  } void t2(){ int i; for(i=0;i<A;i++) {   a[i] += B; } }