Chinaunix首页 | 论坛 | 博客
  • 博客访问: 801737
  • 博文数量: 117
  • 博客积分: 2583
  • 博客等级: 少校
  • 技术积分: 1953
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-06 22:58
个人简介

Coder

文章分类
文章存档

2013年(1)

2012年(10)

2011年(12)

2010年(77)

2009年(13)

2008年(4)

分类: C/C++

2010-11-17 21:54:50

目的是要:

1、设计实验测量打开一个文件需要花费的时间;

2、设计实验验证,打开在kernel被缓冲的文件名的时间,要短于打开一个不在kernel中被缓冲的文件。

实现方法则是在程序中调用open()函数,调用前和调用后分别获取时间,然后将两个时间值相减获得打开一个文件的时间。考虑到open()执行的时间非常的短,通常的用于获取时间的函数的粒度显然不够,所以,用了x86架构都会有的一个时钟周期计数器,这个计数器会记录从开机到当前时刻的CPU时钟周期数,保存在CPU中的一个64位寄存器里。

 

首先,来看实现的几个用于获取时钟周期计数器值的函数(文件cyccounter.c中),获取时钟周期计数器的值还需要用内联汇编:

#include

#include

 

/* Initialize the cycle counter */

static unsigned cyc_hi = 0;

static unsigned cyc_lo = 0;

 

/* Set *hi and *lo to the high and low order bits of the cycle counter.

 * Implementation requires assembly code to use rdtsc instruction.

 */

void access_counter(unsigned *hi, unsigned *lo){

  asm("rdtsc;movl %%edx,%0; movl %%eax,%1" /* Read cycle counter */

      : "=r"(*hi), "=r"(*lo)

      : /* No input */

      : "edx", "eax");

}

 

 

void start_counter(void){

  access_counter(&cyc_hi, &cyc_lo);

}

 

/* Return the number of cycles since the last call to start_counter */

double

get_counter(double *ures){

  unsigned ncyc_hi, ncyc_lo;

  unsigned hi, lo;

  double result;

 

  /* Get cycle counter */

  access_counter(&ncyc_hi, &ncyc_lo);

 

  /* Do double precision subtraction */

  if(ncyc_lo < cyc_lo){

    lo = UINT_MAX - cyc_lo + ncyc_lo;

    ncyc_hi --;

  }

  lo = ncyc_lo - cyc_lo;

  hi = ncyc_hi - cyc_hi;

  result = (double)hi * ( 1 << 30) * 4 + lo;

  if(result < 0){

    fprintf(stderr, "Error: counter returns neg value: %.0f\n", result);

  }

  *ures = result;

  return result;

}

 

然后来看主函数中测量文件打开时间的代码(文件opentime.c中):

#include

#include

#include

#include

#include

#include

#include

#include

#include "opentime.h"

 

int

main(int argc, const char *argv[]){

  int openfd1, openfd2, openfd3;

  double result, reresult;

 

  start_counter();

  openfd1 = open(argv[1], O_RDONLY);

  if(openfd1 < 0){

    printf("open file failed: %s.\n", strerror(errno));

    exit(1);

  }

  reresult = get_counter(&result);

  printf("The time is: %.0f clock cycles.\n", result);

  printf("Return result: %.0f\n", reresult);

 

  start_counter();

  openfd2 = open(argv[1], O_RDONLY);

  if(openfd2 < 0){

    printf("open file failed: %s.\n", strerror(errno));

    exit(1);

  }

  reresult = get_counter(&result);

  printf("The time is: %.0f clock cycles\n", result);

  printf("Return result: %.0f\n", reresult);

 

  start_counter();

  openfd3 = open(argv[1], O_RDONLY);

  if(openfd3 < 0){

    printf("open file failed: %s.\n", strerror(errno));

    exit(1);

  }

  reresult = get_counter(&result);

  printf("The time is: %.0f clock cycles.\n", result);

  printf("Return result: %.0f\n", reresult);

 

  printf("\n");

  close(openfd1);

  close(openfd2);

  close(openfd3);

  return 0;

}

 

opentime.h文件中保存了几个函数的函数原型,在没有声明get_counter()函数原型的时候,总是出现一些莫名其妙的错误。下面是此时执行这一段程序的输出:

The time is: 26460 clock cycles.

Return result: -1076250560

The time is: 5712 clock cycles

Return result: -1076250560

The time is: 1944 clock cycles.

Return result: -1076250560

在主函数中接收的get_counter()函数返回值分明都莫名其妙。C语言中,一个函数默认的未声明原型的情况下会返回int型值,就像一个函数声明时不提供参数列表的话,会被认为接收一个int型参数一样。

 

在声明了函数原型之后,就一切OK了:

The time is: 30144 clock cycles.

Return result: 30144

The time is: 6480 clock cycles

Return result: 6480

The time is: 2220 clock cycles.

Return result: 2220


另外的一个教训是,打开gcc-Wall选项,这些错误确实都还是挺容易查出来的。未声明函数原型,打开gcc-Wall选项之后,gcc有输出:

opentime.c: In function ‘main’:

opentime.c:22: 警告:隐式声明函数 ‘get_counter

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

chinaunix网友2010-11-18 17:19:28

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com