Coder
分类: 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’
chinaunix网友2010-11-18 17:19:28
很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com