用 C 语言计算/检索 CPU 时钟速度的方法?

问题描述 投票:0回答:1

对于一项作业,我一直在尝试开展一个项目,以纯 C 或内联 ASM 形式检查和检索 Linux 上的系统信息。我现在遇到的一个问题实际上是检索时钟速度。

我最初尝试只阅读

__cpuid

__cpuid(0x80000002 + i, eax, ebx, ecx, edx);

我不相信在 AMD CPU 上,时钟速度会包含在该字符串中。现在,我使用

rdtsc
来检索相当准确的数字,但是我越减少忙等待循环的时间,我失去的准确性就越高。到目前为止,这就是我想出的:

static inline uint64_t rdtsc() {
    unsigned int lo, hi;
    asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
    return ((uint64_t)hi << 32) | lo;
}
void calculate_cpu_clock_speed() {
    uint64_t start, end;
    struct timespec ts_start, ts_end;
    double elapsed_time;

    // Get TSC and time at start
    start = rdtsc();
    clock_gettime(CLOCK_MONOTONIC, &ts_start);

    // (~1 ms)
    do {
        clock_gettime(CLOCK_MONOTONIC, &ts_end);
        elapsed_time = (ts_end.tv_sec - ts_start.tv_sec) +
                       (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9;
    } while (elapsed_time < 0.001);  

    end = rdtsc();

    (cycles per second -> Hz -> GHz)
    double clock_speed_hz = (end - start) / elapsed_time;
    double clock_speed_ghz = clock_speed_hz / 1e9;
    
    printf("%.1f0 GHz\n", clock_speed_ghz);
}

有机会更快地实现这个目标吗?

c linux assembly cpu hardware
1个回答
0
投票

以下 C 程序从 sys 文件系统中检索各个 CPU 内核的当前频率。也许这是解决您问题的有效方法。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define PATH_LEN     80
#define CORES         8
#define INDEX_CPU_ID 27

#define PATH "/sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq"


void error(const char *msg) {
  perror(msg);
  exit(errno);
}

int main() {
  char path[strlen(PATH)+1];
  strcpy(path,PATH);

  for(int i=0;i<CORES;i++) {
    path[INDEX_CPU_ID] = i+'0';
    FILE *fp = fopen(path, "r");
    if (fp == NULL) continue;
    
    unsigned int freq;
    if (fscanf(fp, "%u", &freq) != 1)  perror(path);
    printf("CPU %d frequency: %u kHz\n", i, freq);
    fclose(fp);
  }    
}
© www.soinside.com 2019 - 2024. All rights reserved.