如何计算一段.NET代码的CPU使用率?

时间:2011-01-18 13:07:02

标签: .net performance optimization cpu-usage

我们的工具在诊断模式下生成性能日志,但我们跟踪代码执行时间(秒表+毫秒)的性能。

显然它根本不可靠,测试系统的CPU可以被一些随机过程使用,如果你配置的工具配置为运行10个线程而不是2个等,结果将完全不同。

我的问题是:

找出一段代码的正确CPU时间的正确方法是什么(不是整个过程)?

我的意思是CPU时间:

基本上CPU占用了多少周期。我假设对于同一台计算机中的同一段代码,它将始终相同,而不受其他进程的影响。 我可能会在这里找到一些基本的东西,如果是这样,请在评论或答案中启发我。

P.S。在我们的设置

中无法使用分析器

另一个更新,

为什么我不打算使用探查器

因为我们需要在具有不同数据的不同环境中测试代码,而我们没有分析器或IDE或类似的东西。因此代码本身应该处理它。一个极端的选择可能是使用分析器的DLL,但我不认为这个任务需要这么复杂的解决方案(假设没有免费且易于实现的分析库)。

3 个答案:

答案 0 :(得分:4)

  

我认为对于同一台计算机中的同一段代码,它将始终相同,而不受其他进程的影响

这不是计算机的工作方式。代码非常 受到计算机上运行的其他进程的影响。典型的Windows机器有大约1000个活动线程,您可以在Taskmgr.exe的“性能”选项卡中看到该数字。绝大多数人都睡着了,等待Windows发出的某种事件。尽管如此,如果机器正在运行代码,包括你的代码,它已经准备就绪并且需要占用CPU时间,那么Windows将为它们提供所有切片。

这使得测量代码所花费的时间量非常随意。您唯一可以估算的是最短的时间。通过运行测试你做了几十次,你可以得到一个不受其他进程影响的样本。然而,这将永远不会发生在现实生活中,你应该明智地将中位数值作为一个真实的测量值。

唯一真正有用的衡量标准是衡量算法的增量改进。更改代码,看看中间时间因此而变化。

答案 1 :(得分:1)

  

基本上CPU占用了多少周期。一世   假设这将永远是相同的   相同的代码片段   电脑而不受其他影响   流程。可能有一些   我在这里缺少的基本东西,   如果是这样请赐教我   评论或答案。

函数使用的CPU时间是一个非常软弱的概念。

  • 它是否包含在调用树下面的任何位置执行的I / O?
  • 只是“自我时间”或包含被调查者吗? (在严格的代码中,自我时间通常约为零。)
  • 是否对所有调用进行了平均?定义“所有”。
  • 为了什么目的,谁会消费这些信息?找到所谓的“瓶颈”?或者只是某种回归追踪目的?

如果目的不仅仅是测量,而是为了找到值得优化的代码,我认为更有用的概念是 堆栈上的时间百分比 。收集该信息的一种简单方法是在随机的挂钟时间读取函数调用堆栈(在您关注的时间间隔内)。这有以下属性:

  • 它告诉包容性时间百分比。
  • 它提供了行级(不仅仅是函数级)百分比,因此它可以精确定位代码行,无论它们是否是函数调用。
  • 它包括I / O以及CPU时间。 (在严肃的软件中,排除I / O时间并不明智,因为你真的不知道在调用树的下面几层花了多少时间。)
  • 对其他进程或CPU速度的CPU竞争相对不敏感。
  • 不需要高采样率或大量样本来查找昂贵的代码。 (This is a common misconception.) 测量精度的每个附加数字需要大约100倍的样本,但这并不能更精确地找到昂贵的代码。

根据这一原则运作的探查器是Zoom

另一方面,如果目标仅仅是测量,那么用户可以看到更改是否有助于或损害性能,那么需要控制CPU环境,并且我建议使用简单的总体时间测量。

答案 2 :(得分:1)

衡量CPU时间的最佳方法是使用“rdtsc”或“Read Time Stamp Counter”指令。该计数器(CPU本身的一部分)以CPU的内部时钟速度递增。因此,两个读数之间的差异是经过的时钟周期数。如果代码(代码)不是太高级(虽然不太确定),这个计数器可以集成到你的代码中。您可以测量磁盘上的时间,网络上的时间,CPU中的时间等 - 可能性是无穷无尽的。如果将经过时钟周期数除以CPU速度(以兆赫为单位),您将获得经过的微秒数。这是非常好的精度和更好的可能考虑构建一个与CPU使用统计信息接口的GUI。

在您环境的帮助文件中搜索“rdtsc”或“ rdtsc”或“ _rdtsc”。

相关问题