原文地址:http://blog.chinaunix.net/uid-24774106-id-2779245.html

最近搞架构,一直在讨论。听人提到,自行科普了一下,先转发,mark。有机会深入学习。

这里用到了,最后一部分有提及 [dpdk] 熟悉SDK与初步使用 (二)(skeleton源码分析)

   最近发现了rdtsc指令,可以获取CPU指令周期数,喜出望外,wiki了下相关的知识,写了代码利用CPU周期来测量程序的运行时间。
 
    rdtsc指令返回的是自开机始CPU的周期数,返回的是一个64位的值EDX:EAX(高32在EDX,低32位在EAX)。OK,完全可以利用这条指令,测试我们的关注的一段代码的执行效率。
 
    题外话,我兴冲冲的告诉我老大,我发现了一个测量程序性能的好办法,老大淡然的说,不会是rdtsc吧。呵呵我和老大的水平差距还是云泥之别啊。他告诉我可以去Linux Kernel查看内核是如何做的。呵呵,我就照搬了kernel的实现。兼练习以下C和汇编混合编程。
 
    在网上搜索相关的资源看到了陈硕大牛的多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间他给出了几个理由,有兴趣的兄弟可以去读下。
    1多核,不能保证每个核的TSC是一样的。
    2 CPU的时钟频率可变
    3 乱序执行导致测量不准。
    
    文献5指出,指令可能乱序执行,并给出个例子,下面的一段代码,本意是测量fdiv需要的CPU周期,但是,由于乱序执行,第二个rdtsc指令可能在fdiv之前执行,造成,无法测量fdiv的需要的CPU周期。文献给出了解决办法。有兴趣的兄弟可以去阅读参考文献5.
 
 
        rdtsc                   ; read time stamp
        mov     time, eax       ; move counter into variable
        fdiv                    ; floating-point divide
        rdtsc                   ; read time stamp
        sub     eax, time       ; find the differenc
 
参考文献:
 1   深入理解计算机系统
 2   Linux Kernel code
 3   wiki
 
    
 
  • #include 
  • #include
  •  #include<linux/types.h>
  •  
  • #define TIMES 100
  • #define SIZE 1024
  •  
  • __u64 rdtsc()
  • {
  •         __u32 lo,hi;
  •  
  •         __asm__ __volatile__
  •         (
  •          "rdtsc":"=a"(lo),"=d"(hi)
  •         );
  •         return (__u64)hi<<32|lo;
  • }
  •  
  • int myfunction()
  • {
  •         int i;
  •         char *p = NULL;
  •         for(i = 0;i<TIMES;i++)
  •         {
  •                 p = (char*)malloc(SIZE*sizeof(char));
  •                 if(p)
  •                 {
  •                     free(p);
  •                 }
  •                 else
  •                 {
  •                     printf("malloc failed when i = %d\n",i);
  •                 }
  •         }
  •         return 0;
  • }
  • int test_rdtsc()
  • {
  •         __u64 begin;
  •         __u64 end;
  •  
  •         begin = rdtsc();
  •         myfunction();
  •         end = rdtsc();
  •         printf("myfunction cost %llu CPU cycles\n",end-begin);
  •         return 0;
  • }
  •  
  • int main()
  • {
  •        test_rdtsc();
  •         return 0;
  • }
  •     执行结果如下
        
  • root@libin:~/program/assembly/rdtsc# ./test
  • myfunction cost 310949 CPU cycles
  •  

    相关文章:

    • 2022-12-23
    • 2022-12-23
    • 2021-12-07
    • 2021-10-27
    • 2022-01-28
    • 2021-09-16
    • 2021-11-23
    • 2021-09-07
    猜你喜欢
    • 2021-05-25
    • 2022-01-02
    • 2022-12-23
    • 2021-11-22
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    相关资源
    相似解决方案