千家信息网

AIX下C/C++函数性能统计实现方法

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,在AIX中,xlc编译器有个选项-qfunctrace,使用此选项编译的程序,自动会在每个函数的入口出口处调用以下自定义函数。extern "C" void__func_trace_enter(con
千家信息网最后更新 2025年02月01日AIX下C/C++函数性能统计实现方法

在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。

  • #include <iostream>
  • #include <vector>
  • #include <string>
  • #include <sys/time.h>

  • using std::vector;
  • using std::string;
  • using std::clog;
  • using std::endl;

  • extern "C" void print_trace();

  • struct Stat
  • {
  • int lvl;
  • string name;
  • long stm;
  • long etm;
  • long oitv;
  • Stat(int l, const string& s, long st) : lvl(l), name(s), stm(st), etm(0), oitv(0) {}
  • };

  • static vector<Stat> tracev;
  • static int clvl = 0;

  • extern "C" void
  • __func_trace_enter(const char * const proc_name,
  • const char * const file_name,
  • const int line_no,
  • void ** const id)
  • {
  • // printf("{ %s (%s:%d) %p %s\n", proc_name, file_name, line_no, id[0], (char*)*id);
  • struct timeval nowtm;
  • gettimeofday(&nowtm, NULL);
  • ++clvl;
  • tracev.push_back(Stat(clvl, string(proc_name)+"() : "+file_name, nowtm.tv_sec * 1000000 + nowtm.tv_usec));
  • }

  • extern "C" void
  • __func_trace_exit(const char * const proc_name,
  • const char * const file_name,
  • const int line_no,
  • void ** const id)
  • {
  • // printf("} %s (%s:%d) %p %s\n", proc_name, file_name, line_no, id[0], (char*)*id);
  • struct timeval nowtm;
  • int itv;
  • gettimeofday(&nowtm, NULL);
  • auto iter = tracev.end() - 1;
  • while (iter->etm != 0)
  • --iter;
  • iter->etm = nowtm.tv_sec * 1000000 + nowtm.tv_usec;
  • itv = iter->etm - iter->stm - iter->oitv;
  • for (auto s = tracev.begin(); s!=tracev.end(); s++)
  • {
  • if (s->etm == 0)
  • s->oitv += itv;
  • }
  • --clvl;
  • if (clvl == 0)
  • print_trace();
  • }

  • extern "C" void print_trace()
  • {
  • time_t t;
  • char buf[30];
  • for (auto s = tracev.begin(); s!=tracev.end(); s++)
  • {
  • clog << s->lvl << "\t";
  • t=s->stm/1000000;
  • strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", localtime(&t));
  • clog << buf << "." << s->stm % 1000000 << "\t";
  • t=s->etm/1000000;
  • strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", localtime(&t));
  • clog << buf << "." << s->etm % 1000000 << "\t";
  • clog << s->etm-s->stm << "\t" << s->oitv << "\t" << s->etm-s->stm-s->oitv << "\t";
  • clog << string(s->lvl-1, ' ') << s->name << endl;
  • }
  • }


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

  • #include <stdio.h>

  • int f2(int i)
  • {
  • return i*2;
  • }

  • int f1(int i)
  • {
  • return f2(i+1);
  • }

  • int main(int argc, char **argv)
  • {
  • for (int i=0;i<2;i++)
  • f1(i);
  • }


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

  • all:
  • xlC -bnoentry -G -o libfunctr.so -qlanglvl=extended0x tr.cpp
  • chmod go-rwx libfunctr.so
  • 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

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

    函数 编译 程序 代码 效果 时间 性能 统计 例子 入口 出入口 出口处 功能 层次 文件 源文件 源程序 编译器 出口 演示 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 sql数据库开发 网络安全监管存在的困难 坦闪国际服登不上服务器 约定钢琴谱软件开发 网络安全小学生锦囊妙计 网络技术发明创造 网络安全法的四大主体国家 奉贤区一站式数据库服务报价行情 手机怎么注册服务器 sip网络电话服务器 网络安全培训学校名称 为什么换岗位到网络安全 如何显示服务器当前时间 六安科凡网络技术有限公司 网络安全科技馆展示 长沙蓝翔职业技术学院软件开发 大学生网络安全预案 湖南政府企业网络安全 爱民社区网络安全 安装数据库时排序规则为十进制 网络安全手抄报4月15什么节 戴尔r740服务器内存条插法 新天骄数据库 网络安全法的四大主体国家 江苏服务器不锈钢外壳加工 闵行区智能化软件开发品质保障 软件开发免费推广平台有哪些 pc应用软件开发环境 长沙蓝翔职业技术学院软件开发 网络安全国家安全 高度
    0