23

我的 Delphi 2006 应用程序存在一些性能问题。你能推荐任何可以帮助我找到瓶颈的分析工具吗

即像turbo Profiler这样的工具

4

9 回答 9

25

不久前我问了同样的问题

我已经下载并尝试了 AQtime。它看起来确实很全面,但它不是一个易于使用的工具,而且对于单个程序员来说非常昂贵(即 600 美元)。我喜欢它是非侵入性的(没有更改您的代码),并且它可以进行逐行分析,直到我发现因为它是一个检测分析器,它可能导致不正确的优化,如下所示:为什么 CharInSet 比 Case 语句快?

我尝试了 ProDelphi 的演示,价格便宜得多(我认为大约 80 美元),但它对我来说太笨重了——我根本不喜欢用户界面,而且它是侵入性的——更改代码以添加检测,你必须小心。

我使用 GpProfile 和 Delphi 4 很多年了。我爱它。它也是侵入性的,但它运作良好,我学会了信任它,而且它在 10 年内从未给我带来任何问题。但是当我升级到 Delphi 2009 时,我认为最好不要尝试使用它,因为它还没有升级,而且 GP 承认,不修改就无法工作。我希望您也无法在 Delphi 2006 中使用它。

ProDelphi 和 GpProfile 将仅在过程级别进行分析。如果你想做单独的行(我有时不得不这样做),你必须为每一行调用 PROC1、PROC2、PROC3 并将一行放在每个 PROC 中。不得不这样做有点烦人,但它给了我很好的结果(至少我对 GpProfile 这样做的结果感到满意)。

我在 CharInSet 问题中接受的答案是“定期检查 CPU 位置的采样分析器通常更适合测量代码时间。” 后来的回答给了 Eric Grange 的 Delphi 免费采样分析器,现在支持 Delphi 2009。我还没有尝试过,但我听说过它的好消息,这是我要尝试的下一个。

顺便说一句,您最好不要购买 AQtime 来节省 600 美元,而是使用它来将您的 Delphi 2006 升级到 Delphi 2009。稳定性、速度和额外的功能(特别是 Unicode)值得您花时间。请参阅:升级到 D2009(Unicode 除外)的主要激励措施是什么?

AQtime 还没有集成到 Delphi 2009 中。

另一个免费的,我发现但尚未尝试过的来源是TProfiler。如果有人试过那个,我想知道他们的想法。


注意:我后来添加到问题 291631的附录似乎可能是答案。查看Andre 的开源程序:asmprofiler


2010 年 2 月随访。我硬着头皮买了AQTime。几个月前,他们终于将它集成到我使用的 Delphi 2009 中(但他们仍然必须使用 Delphi 2010)。查看源代码行及其各个时间和计数对我来说非常宝贵,而 AQTime 在这方面做得非常出色。

于 2008-12-15T22:41:53.543 回答
11

我刚刚找到了一个非常不错的免费 采样分析器,它支持 Delphi 2009

于 2009-03-08T12:11:27.217 回答
10

我用过 ProDelphi,主要是为了确定哪些例程消耗的时间最多。它是一个 Instrumenting Profiler,这意味着它会在每个例程的开头和结尾添加一些代码。您可以通过注释中的指令控制它配置的例程。您还可以分析例程的各个部分。但是这些部分必须在同一块级别开始和停止,没有进入或退出该部分。优化必须在 ProDelphi 插入其代码的地方(放置指令的地方)关闭,但您可以在其他任何地方打开它。

界面有点笨拙,但是一旦掌握了它就会非常快。您可以使用免费版本(限于 10 个例程或部分)进行有用的工作。ProDelphi 可以快速告诉您应该检查哪些例程。但不是为什么,或者是哪一行。

最近,我开始使用英特尔的 VTune 性能分析器。“哇”并没有开始总结它。我印象深刻。我根本不知道所有这些都内置在现代英特尔处理器中。您是否知道它可以准确地告诉您在从更高的缓存重新加载一个字之前,一条指令需要多长时间等待 L1 数据缓存侧向查看另一个内核?如果我继续写下去,我听起来就像是一个令人窒息的产品广告。

前往英特尔并下载完整的定时演示。在网上挖掘并找到一些关于如何开始的视频。(否则,您将面临被所有选项所阻碍的风险。)它适用于任何编译器。只需将其指向 .exe。如果您的 .exe 包含调试信息并且您将其指向源代码,它将向您显示源代码行。


我被困在试图优化一个调用我编写的函数的内部循环。除了长度(str)之外,没有外部调用。这个内部循环每次运行数十亿次,消耗了大约一半的 CPU 时间——这是优化的完美候选者。我尝试了各种标准优化,几乎没有效果。VTune 显示热点。我只是深入研究,直到它向我展示了我的代码生成的 ASM,以及每条指令花费了多少时间。

这是 VTune 告诉我的:

  • line nnnn [delphi 代码行] ...
  • addr hhhh cmp byte ptr [edx+ecx],0x14h - - - - - - - - 3 个周期
  • addr hhhh ja label_x - - - - - - - - - - - - - - - - -10302 个周期

绝对值没有任何意义。(我想我是在测量每条退役指令的周期。)相对值很清楚所有时间都去了哪里。最棒的是建议窗口。它告诉我代码停止等待数据加载到 L1 数据缓存中,实际上给了我关于如何避免停止的很好的建议。

我的错误在于将 Core2 Quad 视为一个非常快的 8086 CPU。没有^3。代码花费了 99% 的时间等待从内存中加载数据,因为我跳的太多了。我的算法假设内存是 RAM(随机存取)。这不是现代 CPU 的工作方式。L1 缓存中的数据可能会在 1 或 2 个周期内被访问,但访问 L2 或 L3 缓存需要数十到数百个周期,而进入 RAM 则需要数千个周期。 但是,当您按顺序访问数据时,所有这些延迟都可以避免——因为处理器会在您请求的第一个字节之后使用数据预加载缓存。

最终结果是我重写了算法以更顺序地访问数据,并获得了 10 倍的加速,这已经足够好了。当我有时间时,我确信我可以再获得 10 倍的收益。但这只是我心中的极客。够好就够了。

我已经知道通过优化算法而不是代码来获得最大的收益。我以为我只需要探查器告诉我需要优化什么。但我也需要它来找出瓶颈的原因,这样我就可以设计一个更快的算法。

The new algorithm isn't radically different from the old. It just stores the data such that it can be accessed sequentially. For example, in one place I moved a field from an array of records into it's own array of integers -- because the inner loop didn't need the rest of the data in each record. I also had a rectangular matrix stored as a dynamic array of dynamic arrays. The code used this to randomly access megabytes of data (and the poor L1 data cache is only 64Kb). I figured out how to store it in a linear array as diagonals of the matrix, which is the order I use the data. (OK, maybe that part is radical.)

Anyway, I'm sold on VTune.

于 2009-07-13T21:46:26.580 回答
6

我过去曾在 Delphi 7 项目上成功使用过http://www.prodelphi.de 。便宜又好用。不要让丛林联盟网站吓跑你。

于 2008-12-15T16:48:09.980 回答
3

www.AutomatedQA.com 拥有 Delphi profiling (AQTime) 的最佳选择

于 2008-12-15T16:40:08.937 回答
3

我使用并推荐 Sampling Profiler,我想你可以从 embarcadeiro.public,attachments 新闻组获得它。

于 2008-12-15T19:25:10.337 回答
0

这是另一种选择,我之前没有使用过这个:http: //www.prodelphi.de

于 2008-12-15T16:43:36.277 回答
0

我知道的 Delphi 的最终选择, http: //gp.17slon.com/gpprofile/index.htm

于 2008-12-15T16:44:34.717 回答
-1

最后一点,www.torry.net 是 Delphi 组件/工具搜索的好地方

于 2008-12-15T16:45:17.227 回答