c - 在内核中使用 rdtsc 测量执行时间

标签 c linux linux-kernel

我正在编写代码,通过将代码作为模块加载到内核中来测量内核中一系列代码的时间消耗。我使用常见的 rdtsc 例程来计算时间。有趣的是,在用户模式下运行的类似例程会产生正常值,而在内核模式下运行时结果始终为 0,无论我在 time_count 函数中添加了多少行代码。我这里使用的计算是一个普通的矩阵乘积函数,运行周期应该随着矩阵维数的增加而快速增加。谁能指出我的代码中的错误,为什么我无法测量内核中的周期数?

#include <linux/init.h>
#include <linux/module.h>

int matrix_product(){
  int array1[500][500], array2[500][500], array3[500][500];
  int i, j, k, sum;

  for(i = 0; i < 50000; i++){
    for(j = 0; j < 50000; j++){
      array1[i][j] = 5*i + j;
      array2[i][j] = 5*i + j;
    }
  }

  for(i = 0; i < 50000; i++){
    for(j = 0; j < 50000; j++){
      for(k = 0; k < 50000; k++)
    sum += array1[i][k]*array2[k][j];
      array3[i][j] = sum;
      sum = 0;
    }
  }
  return 0;
}

static __inline__ unsigned long long rdtsc(void)
{
 unsigned long hi, lo;
 __asm__ __volatile__ ("xorl %%eax,%%eax\ncpuid" ::: "%rax", "%rbx", "%rcx", "%rdx");
 __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
 return ((unsigned long long)lo) | (((unsigned long long)hi)<<32) ;
}

static int my_init(void)
{
  unsigned long str, end, curr, best, tsc, best_curr;
  long i, t;

#define time_count(codes) for(i=0; i<120000; i++){str=rdtsc(); codes; end=rdtsc(); curr=end-str; if(curr<best)best=curr;}

 best = ~0;
 time_count();
 tsc = best;

 best = ~0;
 time_count(matrix_product());
 best_curr = best;
 printk("<0>matrix product: %lu ticks\n", best_curr-tsc);

 return 0;
}

static void my_exit(void){
  return;
}

module_init(my_init);
module_exit(my_exit);`

感谢任何帮助!谢谢。

最佳答案

rdtsc 不保证在每个 CPU 上都可用,或以恒定速率运行,或在不同内核之间保持一致。

除非您对时间戳有特殊要求,否则您应该使用像 getrawmonotonic 这样可靠且可移植的函数。

如果你真的想直接使用循环,内核已经定义了get_cyclescpuid为此的功能。

关于c - 在内核中使用 rdtsc 测量执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20255329/

相关文章:

C 程序在 For 循环中崩溃

c - 在进行浮点除法时加倍和返回时是否有任何精度增益?

r - 替代Linux中R的 `memory.size()`?

linux - spin_lock 和 spin_unlock 是否会影响单 cpu 机器上 SMP 内核的性能?

linux - GDB:lx-symbols 未定义命令

c - 全局描述符表的物理地址?

c - 数组指针编译时警告 : warning: initialization from incompatible pointer type

c - 在范围内,所有声明都会在编译后发生在函数的开头吗(在 C 中)?

ruby - 安装完整的 ruby​​ 后要使用什么 shebang 行?

linux - 将列添加到文件末尾