在*nix上分析C/C++应用程序的最佳工具是什么?
(我希望能够分析一个混合了(阻塞)文件IO,epoll for network和fork()/ execv()的服务器来解决一些繁重的问题;但是一般的帮助和更一般的工具都很受欢迎.)
您是否可以在一个概述中获得RAM,CPU,网络和磁盘的大系统图片,并深入研究它?
在内核列表上有很多关于类似事情的讨论perf timechart,但我还没有发现Ubuntu中出现过任何问题.
精简版:
是否有适合Linux的基于良好时间的采样分析器?
长版:
我通常使用OProfile来优化我的应用程序.我最近发现了一个令我疑惑的缺点.
问题是紧密循环,产生c ++ filt来解码c ++名称.在追逐另一个瓶颈时,我偶然偶然发现了代码.OProfile没有显示代码的任何异常,所以我几乎忽略了它,但我的代码意识告诉我优化调用,看看发生了什么.我将popenc ++ filt 更改为abi::__cxa_demangle.运行时间从一分多钟到一秒多一点.大约x60加速.
有没有办法我可以配置OProfile标记popen呼叫?随着配置文件数据的出现,现在OProfile认为瓶颈是堆和std::string调用(BTW一旦优化就将运行时间降低到不到一秒,超过x2加速).
这是我的OProfile配置:
$ sudo opcontrol --status
Daemon not running
Event 0: CPU_CLK_UNHALTED:90000:0:1:1
Separate options: library
vmlinux file: none
Image filter: /path/to/executable
Call-graph depth: 7
Buffer size: 65536
Run Code Online (Sandbox Code Playgroud)
还有另一个Linux的分析器可能找到了瓶颈吗?
我怀疑问题是OProfile只将其样本记录到当前正在运行的进程中.我希望它始终将其样本记录到我正在分析的过程中.因此,如果当前流程已被切换(阻止IO或popen呼叫),OProfile只会将其样本置于阻塞的呼叫中.
如果我无法修复此问题,OProfile仅在可执行文件接近100%CPU时才有用.它对于具有低效阻塞调用的可执行文件无能为力.
F#Interactive(以及一般的REPL样式工具)是性能分析的理想入口.有什么比选择代码块并将其直接发送到将返回性能分析报告的分析器更容易的事情.不幸的是,现有的分析器看起来没有REPL支持:您必须将分析器附加到进程或指定可执行文件或Web应用程序以进行分析.
我最终要做的是将代码块包装到单元测试中的配置文件,然后针对NUnit命令行会话执行配置文件.但这是我们现在用F#做的最好的事情吗?
我想提高Python脚本的性能,并一直cProfile用于生成性能报告:
python -m cProfile -o chrX.prof ./bgchr.py ...args...
Run Code Online (Sandbox Code Playgroud)
我chrX.prof用Python 打开了这个文件pstats并打印出统计信息:
Python 2.7 (r27:82500, Oct 5 2010, 00:24:22)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pstats
>>> p = pstats.Stats('chrX.prof')
>>> p.sort_stats('name')
>>> p.print_stats()
Sun Oct 10 00:37:30 2010 chrX.prof
8760583 function calls in 13.780 CPU seconds
Ordered by: function name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 {_locale.setlocale} …Run Code Online (Sandbox Code Playgroud) 我来自Matlab背景,所以我习惯了一个分析器,它可以描述每一行而不仅仅是每个函数都像gprof或callgrind.有没有C类似功能的探查器?
谢谢!

在尝试优化代码时,我对由kcachegrdind和生成的配置文件的差异感到有些困惑gprof.具体来说,如果我使用gprof(使用-pg交换机编译等),我有这个:
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
89.62 3.71 3.71 204626 0.02 0.02 objR<true>::R_impl(std::vector<coords_t, std::allocator<coords_t> > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&) const
5.56 3.94 0.23 18018180 0.00 0.00 W2(coords_t const&, coords_t const&)
3.87 4.10 0.16 200202 0.00 0.00 build_matrix(std::vector<coords_t, std::allocator<coords_t> > const&)
0.24 4.11 0.01 400406 0.00 0.00 std::vector<double, std::allocator<double> >::vector(std::vector<double, std::allocator<double> > const&)
0.24 4.12 0.01 100000 …Run Code Online (Sandbox Code Playgroud) 编写Bespin(基于云的基于画布的代码编辑器[以及更多])的人最近谈到了他们如何重新考虑和优化Bespin代码的一部分,因为他们误以为JavaScript很慢.事实证明,当所有的说法和完成时,他们的优化没有产生显着的改进.
我相信我们很多人都会根据类似于Bespin团队的误解编写"优化"代码.
开发人员通常订阅的常见性能瓶颈误区是什么?
我正在努力实现术语Web服务的模糊搜索,我正在寻找关于如何改进当前实现的建议.分享的代码太多了,但我认为解释可能足以提出深思熟虑的建议.我意识到这是很多东西,但我很感激任何帮助.
首先,术语基本上只是一些名称(或术语).对于每个单词,我们按空格将其拆分为标记,然后遍历每个字符以将其添加到trie.在终端节点上(例如当达到草莓中的字符y时),我们在列表中存储主术语列表的索引.因此,终端节点可以具有多个索引(因为草莓的终端节点将匹配'草莓'和'对草莓过敏').
对于实际搜索,搜索查询也按空间分解为标记.为每个令牌运行搜索算法.搜索令牌的第一个字符必须匹配(因此traw永远不会匹配草莓).之后,我们通过每个连续节点的子节点.如果有匹配的字符的子项,我们继续使用搜索令牌的下一个字符进行搜索.如果孩子与给定的角色不匹配,我们会使用搜索令牌的当前角色来查看孩子(因此不会推进它).这是模糊部分,因此'stwb'将匹配'草莓'.
当我们到达搜索令牌的末尾时,我们将搜索该节点处的其余trie结构以获得所有可能的匹配(因为到主术语列表的索引仅在终端节点上).我们称之为卷起.我们通过在BitSet上设置它们的值来存储索引.然后,我们简单地从每个搜索令牌的结果中得到BitSets.然后,我们从anded BitSet中获取前1000或5000个索引,并找到它们对应的实际项.我们使用Levenshtein对每个术语进行评分,然后按分数进行排序以获得最终结果.
这种方法效果很好而且非常快.树中有超过390k个节点,超过110万个实际术语名称.但是,现在存在问题.
例如,当我们不想要它时,搜索'car cat'将返回Catheterization(因为搜索查询是两个单词,结果应该至少为两个).这很容易检查,但它不会像导管过程那样处理,因为它是两个字.理想情况下,我们希望它与Cardiac Catheterization相匹配.
基于纠正这个问题的需要,我们想出了一些改变.首先,我们通过混合深度/广度搜索来检查trie.基本上,只要角色匹配,我们就会先进入深度.那些不匹配的子节点将添加到优先级队列中.优先级队列按编辑距离排序,可以在搜索特里时计算(因为如果有字符匹配,则距离保持不变,如果不匹配,则增加1).通过这样做,我们得到每个单词的编辑距离.我们不再使用BitSet了.相反,它是Terminfo对象的索引映射.此对象存储查询短语的索引以及术语短语和分数.因此,如果搜索是"汽车猫"并且匹配的术语是"导管过程" 术语短语索引将是1,查询短语索引也是如此.对于"心脏导管",术语短语索引将是1,2,查询短语索引也是如此.正如您所看到的,之后查看术语短语索引和查询短语索引的计数非常简单,如果它们不至少等于搜索词计数,则可以将它们丢弃.
之后,我们将单词的编辑距离相加,从与术语短语索引匹配的术语中删除单词,并计算剩余的字母以获得真正的编辑距离.例如,如果您将术语"过敏与草莓"匹配并且您的搜索查询为"稻草",您将从草莓中获得7分,那么您将使用术语短语索引从该术语中丢弃草莓,并且只计算"过敏"(减去空格)得分为16分.
这让我们得到了我们期望的准确结果.但是,它太慢了.在一个单词搜索之前我们可以获得25-40毫秒,现在它可能多达半秒.它主要来自实例化TermInfo对象,使用.add()操作,.put()操作以及我们必须返回大量匹配这一事实.我们可以将每次搜索限制为仅返回1000个匹配,但不能保证"car"的前1000个结果将匹配"cat"的前1000个匹配中的任何一个(记住,有超过1.1万个术语).
即使对于像cat一样的单个查询词,我们仍然需要大量的匹配.这是因为如果我们搜索'cat',搜索将匹配汽车并汇总其下方的所有终端节点(这将是很多).但是,如果我们限制结果的数量,则会过于强调以查询开头而不是编辑距离的单词.因此,像导尿管这样的词语比涂层更容易被包括在内.
那么,基本上,对于我们如何处理第二个实现修复的问题有什么想法,但没有引入的速度减慢那么多吗?我可以包含一些选定的代码,如果它可以使事情更清楚,但我不想发布一个巨大的代码墙.
java algorithm performance fuzzy-search levenshtein-distance
我需要在Windows上分析一个实时的C++应用程序.大多数可用的分析器要么非常昂贵,要么完全过度,或者两者兼而有之.我不需要任何.NET东西.由于它是一个实时应用程序,我需要尽可能快的分析器.如果它以某种方式与Visual Studio 2005/2008集成,那将是非常好的,但这不是必需的.如果这个描述提醒您使用的探查器,我真的很想知道它.我希望借助人们在Windows上使用C++分析器来确定能够完成这项工作的人.谢谢.
我不懂gprof的文档,关于如何使用gprof编译程序以进行性能分析.在g ++中,是否需要使用-g选项(调试信息)进行编译,-pg或者不添加选项.在每种情况下,我得到不同的结果,我想看看我的应用程序中的瓶颈在哪里处于发布模式,而不是在调试模式中,编译器遗漏了许多优化(例如内联)