使用rdtsc测试程序的运行速度


             最近发现了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<stdio.h> 
2.
#include<stdlib.h>
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\n",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\n",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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值