Chinaunix首页 | 论坛 | 博客
  • 博客访问: 248734
  • 博文数量: 44
  • 博客积分: 1052
  • 博客等级: 少尉
  • 技术积分: 742
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-17 16:51
文章分类

全部博文(44)

文章存档

2013年(7)

2012年(14)

2011年(23)

分类: C/C++

2011-10-10 17:36:16

看到《程序设计实践》一书上第7章讲“测试”,里面有一小节描述了作者测试在自己机器上一些操作的耗时。
如整数的加减乘除,浮点数的加减乘除。觉得很有意思,就按照书上的想法,自己写了一个测试集。写的并不好,不过应该没多大问题。

首先要解决的问题是计时,我找到了三个方法:
(1)用C标准库里的clock()函数,问题是精度不够。顶多是毫秒。
 (2) 用linux系统的库函数gettimeofday(),可以精确到微秒。似乎还有一个clock_gettime()函数也很不错。
 (3) 用CPU指令,说是CPU里有一个计数器,可以用RDTSC指令来取出当前计数,这样分别取出两个计数,然后除以机器的主频,就能得到时间了,精确到纳秒级。

第一种精度太低,第三种太麻烦,关于第三种在网上有很多资料。我选第二种。
基本的计时代码结构是:
  1. #include <sys/time.h>
  2. ...

  3. struct timeval start, end;
  4. double ns;

  5. gettimeofday(&start, NULL);  
  6. /* code */
  7. for(i = 0; i < N; i++)
  8.     ival++;
  9. gettimeofday(&end, NULL);

  10. ns = 1e3*(1e6*(end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec);
  11. true_time = ns / N;
这里我还是将时间转成了纳秒刻度。
计时中间的代码就是一个循环, 因此最终时间还要除一个循环次数。

下面是我测试的结果,
我的电脑双核处理器:Pentium(R)Dual-Core CPU T4300@2.10GHz, ubuntu10.10系统。
gcc 4.4.5编译器,编译时候没开启优化选项。
后面的数字是时间,单位是纳秒
null loop: 3.360577      # 空循环

# 整数的操作
ival++: 3.352575
++ival: 3.352027
ival1+ival2: 3.864244
ival1-ival2: 3.258683
ival1*ival2: 3.679492
ival1/ival2: 4.871335
ival1%ival2: 4.876412

# 单精度浮点操作
fval1+fval2: 3.734369
fval1-fval2: 3.713846
fval1*fval2: 3.638461   # 可见浮点乘耗时并不多,不过除就很多了。
fval1/fval2: 10.947827

# 双精度浮点操作
dval1+dval2: 3.161844
dval1-dval2: 2.819050
dval1*dval2: 2.514910   # 双精度并不一定比单精度计算的慢
dval1/dval2: 10.611016

# 数组操作
a[i]=i: 4.019270
a[a[i]]=i: 5.042540
a[a[a[i]]]=i: 7.507980

# 分支
if(i==5): 3.749296
if(i!=5): 4.310709

# 函数调用
func(): 3.363777
func(a): 3.414053
func(a, b): 3.964201
func(a, b, c): 4.341260      # 多一些参数,应该就多了一些压栈操作

# string库里的三个函数
strcpy(d, "0123456789"): 17.458487
memcpy(d, "0123456789"): 10.090370      # 还是memcpy要快一些
strcmp(s, s): 3.424462


在我的测试中,我觉得最不可思意的是下面的代码:
  1. #include <stdio.h>
  2. #include <time.h>

  3. #define N 0x7FFFFFFFU
  4. int main()
  5. {
  6.     unsigned int i;
  7.     double a,b,c;
  8.     unsigned long long t;
  9.     clock_t c_start, c_end;
  10.     printf("%d\n", sizeof(clock_t));

  11.     a = 2.3928318;
  12.     b = 83.328321;

  13.     c_start = clock();
  14.     for(i = 0; i < N; i++)
  15.         ; /* null loop */
  16.     c_end = clock();
  17.     t = c_end - c_start;
  18.     printf("%llu\n", t);

  19.     c_start = clock();
  20.     for(i = 0; i < N; i++)
  21.         c = a * b; /* float multi */
  22.     c_end = clock();
  23.     t = c_end - c_start;
  24.     printf("%llu\n", t);

  25.     return 0;
  26. }
运行后,我这测得的时间是:
4
7190000
5220000

数字4是clock_t占的字节数。
可见双精度浮点运算的时间要比空的循环还要少。 不得其解!

我在winXP下测试时,浮点运算要比空循环时间多那么一小点。

阅读(5162) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~