免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4074 | 回复: 19

[C] 问一下大家用什么方法计时以获取程序的效率? [复制链接]

论坛徽章:
0
发表于 2012-09-04 20:46 |显示全部楼层
程序很大,可优化的点也很多,我想通过计算函数的累计执行时间来指明一个优化方向。我知道的计时有这么几种:

1. time(C库,只能到秒)
2. gettimeofday / clock_gettime(Linux only),GetTickCount/QueryPerformanceCounter(Windows only)
3. GetThreadTimes (Windows only,只计算User和Kernel两部分)

我用的是第三种。

第一种精度太低。起码也得按毫秒算吧。

第二种精度都可以,但是它计算的是绝对时间。如果运行过程中计算机很卡,计算出来的值会有很大误差。

第三种精度也足够,而且受其他进程/线程的影响较小,但是他本身好像很费时间,同一个程序里面用的场合越多,程序越慢,平均个场合要因为调用GetThreadTimes耗费200多ms。

像这种效率测试的方法大家也可以提一提。

论坛徽章:
0
发表于 2012-09-04 20:54 |显示全部楼层
还有,我知道gprof可以自动完成这个功能,但是我用的vs。。。。

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
发表于 2012-09-04 20:57 |显示全部楼层
gettickcount

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-09-04 22:24 |显示全部楼层
回复 2# sonicling

既然都提到gprof了(相比1楼提到的那些,这是自动而非手动插入统计),VS其实也有对应的功能的。。。
team suit肯定有。。。 我用过。。。 其他的比如enterprise/professional/standard神马的就不清楚了。。。

至于精度。。。  整体的用gprof(或者VS team suit提供的功能)测。。。  局部的用1楼的甚至RDTSC(要小心多核)之类的。。。
C/C++都不提供标准的profile工具,摔。。。

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
发表于 2012-09-04 22:29 |显示全部楼层
还有一个oprofile。

论坛徽章:
0
发表于 2012-09-04 23:00 |显示全部楼层
time   ./xxx.out

论坛徽章:
0
发表于 2012-09-04 23:20 |显示全部楼层
回复 4# OwnWaterloo


    我用的VS专业版,有单元测试和顺序测试,不知道TeamSuite是不是有更多的测试。

gprof这类的测试的确很强大。虽然没有用它来测试我目前的项目,但是手头项目的函数很多,相比输出肯定很杂乱,然后又是C++的项目,里面逻辑并不是函数调用那么简单,比如同一组虚函数的实现最好能合并等等。

而且这种工具会往代码里面加点东西,这也会影响最后的结果。不过效果应该比我手动添加计时点要好。

目前我的做法就是针对疑似性能低下的部分手动安插计时器进行计时。
  1. #ifndef __PERF_HEADER__


  2. #ifdef LOCAL_PERF
  3. #undef LOCAL_PERF
  4. #endif
  5. #ifdef CUSTOM_PERF
  6. #undef CUSTOM_PERF
  7. #endif

  8. #if defined(COMPILER_NDEBUG) && defined(COMPILER_PERF)
  9. #define __PERF_HEADER__
  10. #include "timecounter.h"
  11. // print performance on destruction
  12. struct local_perf
  13. {
  14.         local_perf(const char *func) : _func_name(func) {};
  15.         ~local_perf()
  16.         {
  17.                 unsigned long span = tc.time();
  18.                 unicout << _T("\"") << _func_name << _T("\" spent ") << span << _T("ms") << std::endl;
  19.         };

  20.         const char *_func_name;
  21.         time_counter tc;
  22. };
  23. #define LOCAL_PERF() local_perf __local_perf__(__FUNCTION__)
  24. #define CUSTOM_PERF(func) local_perf __custom_perf__(func)
  25. #else
  26. #define LOCAL_PERF()
  27. #define CUSTOM_PERF(func)
  28. #endif


  29. #ifdef ACC_PERF
  30. #undef ACC_PERF
  31. #endif
  32. #ifdef CUSTOM_ACC_PERF
  33. #undef CUSTOM_ACC_PERF
  34. #endif
  35. #if defined(COMPILER_NDEBUG) && defined(COMPILER_PERF)
  36. // print performance on destruction, but can accumulate total time for a function
  37. template <typename tag>
  38. struct accumulated_perf
  39. {
  40.         struct static_perf
  41.         {
  42.                 unsigned long _total;
  43.                 const tchar *_func;
  44.                 static_perf(const tchar *func)
  45.                         : _total(0), _func(func) {}
  46.                 ~static_perf()
  47.                 {
  48.                         unicout << _T("\"") << _func << _T("\" spent ") << _total << _T("ms") << std::endl;
  49.                 }
  50.         };
  51. public:
  52.         accumulated_perf(static_perf &perf) : _func_perf(perf) {}
  53.         ~accumulated_perf() {_func_perf._total += _tc.time();}
  54. private:
  55.         time_counter _tc;
  56.         static_perf &_func_perf;
  57. };

  58. #define ACC_PERF() CUSTOM_ACC_PERF(__FUNCTION__)
  59. #define CUSTOM_ACC_PERF(info) struct __anonymous__{};static accumulated_perf<__anonymous__>::static_perf __static_perf__(info); accumulated_perf<__anonymous__> __accumulated_perf__(__static_perf__)
  60. #else
  61. #define ACC_PERF()
  62. #define CUSTOM_ACC_PERF(info)
  63. #endif

  64. #endif
复制代码
确定只调用一次的用前面的LOCAL_PERF,确定会调用多次的用后面的ACC_PERF,只测试某函数的部分代码的用CUSTOM_XXX版本。

原理跟那些自动化工具其实差不多。就是发现GetThreadTimes速度太慢,严重影响结果,GetTickCount又会受到其他进程的影响,鱼和熊掌不可兼得啊。

论坛徽章:
0
发表于 2012-09-04 23:21 |显示全部楼层
1053304571 发表于 2012-09-04 23:00
time   ./xxx.out


这是测试总时间吧,没有指导意义啊。

论坛徽章:
0
发表于 2012-09-04 23:38 |显示全部楼层
记得有个工具可以满足你的需要   待我找找回复 8# sonicling


   

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-09-04 23:41 |显示全部楼层
回复 7# sonicling

呃,不是正确性方面的测试,不是gcov那种东西,就是性能方面的测试。嗯,是TeamSuite,我拼错了。。。
除了gprof那种Instrumentation(你写的那个代码也是一种手工的Instrumentation。。。),还支持Sampling: http://msdn.microsoft.com/en-us/library/ms242753(v=vs.80).aspx

貌似确实只有TS才支持: http://en.wikipedia.org/wiki/Visual_Studio_Team_System_Profiler
http://msdn.microsoft.com/en-us/magazine/cc337887.aspx 这里有一些截图,印象中就是这样的界面。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP