zoukankan      html  css  js  c++  java
  • [daily]使用rdtsc指令,测量程序的运行速度 [转]

    原文地址: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
     
        
     
    1. #include 
    2. #include
    3.  #include<linux/types.h>
    4.  
    5. #define TIMES 100
    6. #define SIZE 1024
    7.  
    8. __u64 rdtsc()
    9. {
    10.         __u32 lo,hi;
    11.  
    12.         __asm__ __volatile__
    13.         (
    14.          "rdtsc":"=a"(lo),"=d"(hi)
    15.         );
    16.         return (__u64)hi<<32|lo;
    17. }
    18.  
    19. int myfunction()
    20. {
    21.         int i;
    22.         char *p = NULL;
    23.         for(i = 0;i<TIMES;i++)
    24.         {
    25.                 p = (char*)malloc(SIZE*sizeof(char));
    26.                 if(p)
    27.                 {
    28.                     free(p);
    29.                 }
    30.                 else
    31.                 {
    32.                     printf("malloc failed when i = %d ",i);
    33.                 }
    34.         }
    35.         return 0;
    36. }
    37. int test_rdtsc()
    38. {
    39.         __u64 begin;
    40.         __u64 end;
    41.  
    42.         begin = rdtsc();
    43.         myfunction();
    44.         end = rdtsc();
    45.         printf("myfunction cost %llu CPU cycles ",end-begin);
    46.         return 0;
    47. }
    48.  
    49. int main()
    50. {
    51.        test_rdtsc();
    52.         return 0;
    53. }
        执行结果如下
        
    1. root@libin:~/program/assembly/rdtsc# ./test
    2. myfunction cost 310949 CPU cycles
     
  • 相关阅读:
    select和epoll原理和区别
    linux网络编程中的基本概念
    linux 基本概念
    进程与线程(1)- 基本概念
    CI持续集成
    git基本操作(入门)
    pytest特色与实用插件
    使用pabot并行执行robotframework用例
    如何编写测试用例
    前端_vue-cli+element-ui+AceEditor+codemirror+electron-vue
  • 原文地址:https://www.cnblogs.com/hugetong/p/6050791.html
Copyright © 2011-2022 走看看