Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15738
  • 博文数量: 6
  • 博客积分: 130
  • 博客等级: 入伍新兵
  • 技术积分: 70
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-08 00:17
文章分类

全部博文(6)

文章存档

2008年(6)

我的朋友
最近访客

分类:

2008-08-27 10:38:54

近来写了个测量延迟的程序,可以测量秒、微秒和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;
}
阅读(681) | 评论(0) | 转发(0) |
0

上一篇:测量延迟的程序

下一篇:没有了

给主人留下些什么吧!~~