IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    DPDK编程开发(3)—时间API

    cjhust发表于 2015-05-18 16:45:34
    love 0

    1、知识百科

    在DPDK库中提供了一个timer模块,负责异步调用一些回调函数、定时操作等等,DPDK的精准定时是依靠hpet模块(和DPDK版本也有关系),在main()->rte_eal_init()->rte_eal_hpet_init()初始化。

    hpet时钟支持:允许内核使用hpet,hpet是替代8524芯片的新一代定时器,i686及以上级别的主板都支持。

    rte_eal_hpet_init()会去打开/dev/hpet设备文件描述符,并映射一块1024大小的内存空间,创建hpet_msb_inc线程(主要更新eal_hpet_msb全局变量)。比如rte_delay_us()会调用rte_get_hpet_cycles()获取全局变量eal_hpet_msb的值,去确定延时是否到达。

    fd = open(DEV_HPET, O_RDONLY);

    eal_hpet = mmap(NULL, 1024, PROT_READ, MAP_SHARED, fd, 0);

    ret = pthread_create(&msb;_inc_thread_id, NULL, hpet_msb_inc, NULL);

    static void

    hpet_msb_inc(__attribute__((unused)) void *arg)

    {

    uint32_t t;

    while (1) {

    t = (eal_hpet->counter_l >> 30);

    if (t != (eal_hpet_msb & 3))

    eal_hpet_msb ++;

    sleep(10);

    }

    }

    返回值

    操作函数

    函数功能

    uint64_t

    rte_get_tsc_hz (void)

    获得TSC的主频(即1s内多少个TSC cycle)

    static uint64_t

    rte_get_tsc_cycles (void)

    获得自从启动以来的TSC cycle数目

    static uint64_t

    rte_get_timer_cycles (void)

    获得自从启动到现在的cylce次数

    static uint64_t

    rte_get_timer_hz (void)

    获得CPU主频(1s多少个cycle)

    void

    rte_delay_us (unsigned us)

    等待至少N微秒

    static void

    rte_delay_ms (unsigned ms)

    等待至少N毫秒

    2、头文件

    #include

    #include <rte_debug.h>

    #include <rte_atomic.h>

    3、操作函数

    rte_delay_ms(unsigned ms)

    函数功能:等待至少ms毫秒。

    rte_delay_us(unsigned us)

    函数功能:等待至少us微秒。

    rte_get_timer_cycles(void)

    函数功能:获得自从启动到现在的cylce次数。

    void

    rte_delay_us(unsigned us)

    {

    const uint64_t start = rte_get_timer_cycles();

    const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6;

    while ((rte_get_timer_cycles() - start) < ticks)

    rte_pause();

    }

    rte_get_timer_hz(void)

    函数功能:获得CPU的主频(即1s 有多少个cycle),同系列CPU中,主频越高性能越好。

    rte_get_tsc_cycles(void)

    函数功能:获得自从启动以来的TSC cycle数目。

    rte_get_tsc_hz(void)

    函数功能:获得TSC的主频(即1s内多少个TSC cycle),经测试和rte_get_timer_hz()结果一样。

    4、知识扩展

    TSC(时间戳计数器)

    TSC是一个64位的时间戳计数器寄存器,汇编指令rdtsc读这个寄存器,Linux在初始化时系统时必须确定时钟信号的频率。

    备注:rte_rdtsc()函数用来获取时间戳计数器。

    const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;

    = rte_get_tsc_hz()/1000000*100

    = 2300*100

    while (1) {

    cur_tsc = rte_rdtsc();

    diff_tsc = cur_tsc - prev_tsc;

    //cur_tsc = 57987057930424634,

    //prev_tsc = 57987057928124602,

    //drain_tsc = 230000

    //rte_get_tsc_hz() = 2299999318~2300MHz

    if (unlikely(diff_tsc > drain_tsc * 10)) { // rte_get_tsc_hz()/1000~1ms

    adns_log_flush();

    prev_tsc = cur_tsc;

    }

    //cur_tsc = 57987769897251014, prev2_tsc = 57987765297251934,

    //(cur_tsc-pre_tsc)/ rte_get_tsc_hz()=经历的秒数

    //drain_tsc = 230000~2300*100

    //rte_get_tsc_hz() = 2299999526~2300MHz

    //rte_get_timer_hz = 2299999526~2300MHz

    diff_tsc = cur_tsc - prev2_tsc;

    if (unlikely(diff_tsc > 2*rte_get_tsc_hz())) { // 2s

    cpu_utili_process();

    prev2_tsc = cur_tsc;

    }

    }

    查看CPU型号

    #cat /proc/cpuinfo |grep name

    image

    查看CPU主频

    #cat /proc/cpuinfo | grep "cpu MHz"

    image

    5、参考资料

    hpet介绍:

    http://blog.csdn.net/linzhaolover/article/details/9302655

    cycleAPI:

    http://dpdk.org/doc/api/rte__cycles_8h.html



沪ICP备19023445号-2号
友情链接