aix下c/c 函数性能统计实现方法-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 301497
  • 博文数量: 40
  • 博客积分: 1
  • 博客等级: 民兵
  • 技术积分: 670
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-31 11:19
个人简介

从事银行核心系统设计开发的程序猿

文章分类

(40)

  • (3)
  • (9)
  • (7)
  • (3)
  • (18)
  • (0)
文章存档

(1)

(4)

(11)

(6)

(18)

我的朋友
最近访客
相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: aix

2017-05-25 00:42:35

在aix中,xlc编译器有个选项-qfunctrace,使用此选项编译的程序,自动会在每个函数的入口出口处调用以下自定义函数。


extern "c" void
__func_trace_enter(const char * const proc_name,
                   const char * const file_name,
                   const int line_no,
                   void ** const id);


extern "c" void
__func_trace_exit(const char * const proc_name,
                   const char * const file_name,
                   const int line_no,
                   void ** const id);


extern "c" void
__func_trace_catch(const char * const proc_name,
                   const char * const file_name,
                   const int line_no,
                   void ** const id);


在函数调用前,执行__func_trace_enter(),函数正常返回后,执行__func_trace_exit()。如果函数是通过throw异常抛出的,那么在异常被catch捕获处,执行__func_trace_catch(),但是遇到catch(...)捕获不会执行。值得注意的是,如果时throw抛出,不会触发__func_trace_exit()。


使用这个功能,可以实现无需修改源程序,进行性能统计的效果。程序如下。


tr.cpp为自定义函数出入口程序,每个函数执行时都会经过。编译成为libfunctr.so。

  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <sys/time.h>

  5. using std::vector;
  6. using std::string;
  7. using std::clog;
  8. using std::endl;

  9. extern "c" void print_trace();

  10. struct stat
  11. {
  12.     int lvl;
  13.     string name;
  14.     long stm;
  15.     long etm;
  16.     long oitv;
  17.     stat(int l, const string& s, long st) : lvl(l), name(s), stm(st), etm(0), oitv(0) {}
  18. };

  19. static vector<stat> tracev;
  20. static int clvl = 0;

  21. extern "c" void
  22. __func_trace_enter(const char * const proc_name,
  23.                    const char * const file_name,
  24.                    const int line_no,
  25.                    void ** const id)
  26. {
  27. // printf("{ %s (%s:%d) %p %s\n", proc_name, file_name, line_no, id[0], (char*)*id);
  28.     struct timeval nowtm;
  29.     gettimeofday(&nowtm, null);
  30.     clvl;
  31.     tracev.push_back(stat(clvl, string(proc_name)"() : "file_name, nowtm.tv_sec * 1000000 nowtm.tv_usec));
  32. }

  33. extern "c" void
  34. __func_trace_exit(const char * const proc_name,
  35.                   const char * const file_name,
  36.                   const int line_no,
  37.                   void ** const id)
  38. {
  39. // printf("} %s (%s:%d) %p %s\n", proc_name, file_name, line_no, id[0], (char*)*id);
  40.     struct timeval nowtm;
  41.     int itv;
  42.     gettimeofday(&nowtm, null);
  43.     auto iter = tracev.end() - 1;
  44.     while (iter->etm != 0)
  45.         --iter;
  46.     iter->etm = nowtm.tv_sec * 1000000 nowtm.tv_usec;
  47.     itv = iter->etm - iter->stm - iter->oitv;
  48.     for (auto s = tracev.begin(); s!=tracev.end(); s)
  49.     {
  50.         if (s->etm == 0)
  51.             s->oitv = itv;
  52.     }
  53.     --clvl;
  54.     if (clvl == 0)
  55.         print_trace();
  56. }

  57. extern "c" void print_trace()
  58. {
  59.     time_t t;
  60.     char buf[30];
  61.     for (auto s = tracev.begin(); s!=tracev.end(); s)
  62.     {
  63.         clog << s->lvl << "\t";
  64.         t=s->stm/1000000;
  65.         strftime(buf, sizeof(buf), "%y%m%d%h%m%s", localtime(&t));
  66.         clog << buf << "." << s->stm % 1000000 << "\t";
  67.         t=s->etm/1000000;
  68.         strftime(buf, sizeof(buf), "%y%m%d%h%m%s", localtime(&t));
  69.         clog << buf << "." << s->etm % 1000000 << "\t";
  70.         clog << s->etm-s->stm << "\t" << s->oitv << "\t" << s->etm-s->stm-s->oitv << "\t";
  71.         clog << string(s->lvl-1, ' ') << s->name << endl;
  72.     }
  73. }


tt.c为演示的例子程序。编译成可执行文件tt。

  1. #include <stdio.h>

  2. int f2(int i)
  3. {
  4.     return i*2;
  5. }

  6. int f1(int i)
  7. {
  8.     return f2(i1);
  9. }

  10. int main(int argc, char **argv)
  11. {
  12.         for (int i=0;i<2;i)
  13.             f1(i);
  14. }


makefile为把tr.cpp编译成so库,给tt.c连接使用(不修改tt.c任何代码)。注意编译tt.c时使用了-qfunctrace和-lc。

  1. all:
  2. xlc -bnoentry -g -o libfunctr.so -qlanglvl=extended0x tr.cpp
  3. chmod go-rwx libfunctr.so
  4. xlc -bdynamic -brtl -qfunctrace -o tt tt.c -l. -lfunctr -lc


执行后,效果如下:
$tt
1       20170429170216.354105   20170429170216.354151   46      27      19      main() : tt.c
2       20170429170216.354123   20170429170216.354137   14      6       8        f1() : tt.c
3       20170429170216.354130   20170429170216.354136   6       0       6         f2() : tt.c
2       20170429170216.354138   20170429170216.354151   13      6       7        f1() : tt.c
3       20170429170216.354144   20170429170216.354150   6       0       6         f2() : tt.c

分别表示:函数的层次,开始时间,结束时间,总耗时(包含嵌套调用),嵌套调用其他函数总耗时,函数自身代码耗时,函数名和源文件名。

阅读(2990) | 评论(0) | 转发(0) |
0

上一篇:

下一篇:

给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图