近来写了个测量延迟的程序,可以测量秒、微秒和CPU周期数三个量级的延迟。具体使用请看代码:
/**
* @file latency.h
* @brief 测试延迟的程序
* @author W.Y.X
* @date 2008-08-27
* @version 1.0
* @history W.Y.X 1.0 2008-08-27 创建此文件
*/
#ifndef _LATENCY_TEST_H
#define _LATENCY_TEST_H
#include
#include
#include
#include
/**
* @def SECOND
* 延迟的计量单位为秒
*/
#define SECOND 0
/**
* @def MICRO_SECOND
* 延迟的计量单位为微秒
*/
#define MICRO_SECOND 1
/**
* @def CPU_CYCLE
* 延迟的计量单位为CPU时钟周期
*/
#define CPU_CYCLE 2
const char* meter[3] = {"seconds", "micro seconds", "cpu cycles"};
/**
* @struct TIME_PACKAGE
* @brief 记录延迟的起始时间和终止时间
*/
struct TIME_PACKAGE
{
struct timeval begin; /**< 微秒计时的开始时间 */
struct timeval end; /**< 微秒计时的结束时间 */
struct timezone zone; /**< 获取timeval时的时区参数 */
unsigned long start; /**< CPU时钟周期的开始时间 */
unsigned long latency; /**< CPU时钟周期的结束时间 */
} time;
/** 记录程序测量延迟的类型 */
int TYPE;
/**
* @brief 记录开始时间
* 汇编指令:rdtsc 是将当前CPU周期数放入eax寄存器
* @param [in] type 延迟计时类型,为SECOND, MICRO_SECOND和CPU_CYCLE
*/
void getbegin( int type )
{
TYPE = -1;
if (type == CPU_CYCLE) {
TYPE = type;
__asm__ __volatile__("RDTSC;"
"movl %%eax,%0;"
:"=r"(time.start));
}
if (type == SECOND || type == MICRO_SECOND) {
TYPE = type;
gettimeofday( &(time.begin), &(time.zone) );
}
}
/**
* @brief 记录结束时间, 计算出延迟并打印延迟
* 汇编指令:rdtsc 是将当前CPU周期数放入eax寄存器
* @return 延迟的时间
*/
unsigned long getlatency()
{
time.latency = 0;
if (TYPE == CPU_CYCLE) {
__asm__ __volatile__("RDTSC;"
"movl %%eax,%0;"
:"=r"(time.latency));
time.latency = time.latency - time.start;
}
gettimeofday( &(time.end), &(time.zone) );
if (TYPE == SECOND)
time.latency = time.end.tv_sec - time.begin.tv_sec;
if (TYPE == MICRO_SECOND)
time.latency = (time.end.tv_sec - time.begin.tv_sec)*1000000 + (time.end.tv_usec - time.begin.tv_usec) ;
printf("latency is %u %s\n", time.latency, meter[TYPE]);
TYPE = -1;
return time.latency;
}
#endif /*_LATENCY_TEST_H */
下面是一个使用这个程序的例子,用来测试select的延时精度
/**
* @file select_latency.c
* @brief 测试select的延迟精度
* @author W.Y.X
* @date 2008-08-27
*/
#include "latency.h"
#include
#include
int main(int argc, char **argv)
{
int type, latency;
struct timeval timedelay;
if (argc != 3) {
printf("usage: select_latency type latency\n");
printf("0: second\n1: micro second\n2: cpu cycle\n");
return 0;
}
type = atoi(argv[1]);
latency = atoi(argv[2]);
printf("set select latency = %d micro seconds\n", latency);
timedelay.tv_usec = latency;
timedelay.tv_sec = 0;
getbegin( type );
select(0, NULL, NULL, NULL, &timedelay);
getlatency();
return 0;
}
阅读(913) | 评论(0) | 转发(0) |