随笔-处理器微架构-测量CPU频率

方法:执行时长/周期数 约等于 1/lscpu 查看到的频率

[1/2] 固定cpu运行频率

随笔-处理器微架构-固定cpu频率 - LiYanbin - 博客园

[2/2] 实验和实验结果

代码:

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/time.h>

#if defined(__i386__) || defined(__x86_64__)
#include <x86intrin.h>
static inline uint64_t read_cycles() {
    unsigned int aux;
    return __rdtscp(&aux);
}
#elif defined(__arm__) || defined(__aarch64__)
static inline uint64_t read_cycles() {
    uint64_t cycle_count;
    asm volatile("mrs %0, pmccntr_el0" : "=r" (cycle_count));
    return cycle_count;
}
#else
#error "Unsupported architecture"
#endif

#define MY_CPU_GHZ       (3.1)
#define TIME_PER_INST_NS (1/MY_CPU_GHZ) // (1*1000*1000*1000)ns/(3.1*1000*1000*1000)Hz = 1/3.1ns
#define TIME_PER_INST_MS (1/(MY_CPU_GHZ*1000*1000))

#define delta_timeval_ms(t1, t2) ((t2.tv_sec - t1.tv_sec) * 1000 + ((float)t2.tv_usec - (float)t1.tv_usec) / 1000)

int work(int limit)
{
    register int k = 0, i = 0, limit_r = limit;
    uint64_t begin = 0, end = 0;

    struct timeval tv1, tv2;

    gettimeofday(&tv1, 0);
    begin = read_cycles();

    for (; i < limit_r; i++) {
        k = k + 1;
    }

    end = read_cycles();
    gettimeofday(&tv2, 0);
    
    printf("LOOP: %i\n",  limit);
    printf("TSC : %ld(=%lfms, Hz:%.1fGHz)\n", end - begin, (end - begin)*TIME_PER_INST_MS, MY_CPU_GHZ);
    printf("%ld.%ld - %ld.%ld = %f\n", tv2.tv_sec, tv2.tv_usec / 1000, tv1.tv_sec, tv1.tv_usec / 1000,
           delta_timeval_ms(tv1, tv2));
    return k;
}

int main(int argc, char *argv[])
{
   work(100000000);
   return 0;
}

执行结果:

$ gcc -g -O0 inc1.c -o app_inc1
$ taskset -c 0 ./app_inc1
LOOP: 100000000
TSC : 100731034(=32.493882ms, Hz:3.1GHz)
1725688663.855 - 1725688663.822 = 32.535999

实际时间是32.535999,执行了100731034个周期,按照频率换算的出的理论时间为32.493882,实际时间与理论时间几乎一样

posted @   LiYanbin  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
点击右上角即可分享
微信分享提示