第二次运行托管应用程序显示的性能与第一次不同

Nir*_*n U 5 api performance benchmarking performancecounter

我有一个基准测试应用程序来测试我编写的一些API的性能.在这个基准测试应用,我基本上使用QueryPerformanceCounter和除以QPC值的差异之后和调用API时,由频率之前得到的时机.但基准测试结果似乎有所不同如果我从不同的驱动器运行应用程序(在同一组Dll上运行相同的可执行文件).此外,在特定驱动器上,第一次运行应用程序,关闭应用程序并再次重新运行它会产生不同的基准测试结果.谁能解释这种行为?我在这里错过了什么吗?

一些更有用的信息:

该行为是这样的:运行该应用程序,关闭它,并重新运行它,在基准测试结果看来,以提高对第二次运行和以后保持不变.在从C盘运行的情况下,此行为更加突出.我还想提一下,我的基准测试应用程序可以选择重新运行/重新测试特定的API,而无需关闭应用程序.我不明白,有jitting参与,但我不明白的是,在应用程序的第一次运行时,当U多次重新运行的API,但不关闭应用程序,表现一对夫妇运行的稳定后,则当您关闭并重新运行同样的测试,性能似乎有所改善.

另外,如何在从不同驱动器运行时考虑性能变化?

[资讯更新]

我做了一个ngen,现在来自同一地点的不同跑步之间的性能差异消失了.即如果我打开基准测试应用程序,运行一次,关闭它并从同一位置重新运行它,它显示相同的值.

但我现在遇到了另一个问题.当我启动从d驱动的应用程序,(相同的启动基准PROG内夫妇的API的迭代)运行几次,然后从开始第三次迭代,所有API的表现似乎由20%左右下降.然后,如果关闭并重新启动应用程序并运行它,前2次迭代,它给出正确的值(相同的值由C获得),然后再次下降的表现超出.从C驱动器运行时看不到此行为.从C盘开始,无论您运行多少次,都非常一致.

我使用大型双数组来测试我的API性能.我担心GC会在测试之间启动,所以我在每次测试之前和之后明确地调用GC.Collect()和GC.WaitForPendingFinalizers().所以我不认为它与GC有任何关系.

我尝试使用AQ时间来了解从第3次迭代开始发生的事情,但有趣的是,当我使用AQ时间分析它运行应用程序时,性能根本没有下降.

性能计数器并不表示任何有趣的IO活动.

谢谢Niranjan

Cra*_*rks 5

运行应用程序会将其可执行文件和其他文件从硬盘驱动器放入操作系统的磁盘缓存(在 RAM 中)。如果稍后再次运行,其中许多文件可能仍在缓存中。RAM 比磁盘快得多。

当然,一个磁盘可能比另一个磁盘更快。


Mik*_*ton 1

我认为这里有多种效果的组合:

首先,在测试工具中多次运行相同的函数,每次使用相同的数据,可能会有所改善,因为:

  • JIT 编译将优化最常运行的代码以提高性能(正如Cory Foy已经提到的)
  • 程序代码将位于磁盘缓存中(正如Crashwork已经提到的)
  • 一些程序代码如果足够小并且执行得足够频繁,就会在CPU缓存中

如果测试工具中函数每次运行的数据都不同,这可以解释为什么再次关闭并运行测试工具可以改善结果:数据现在将位于磁盘缓存中,这不是第一次。

最后,是的,即使两个“驱动器”位于同一物理磁盘上,它们也会具有不同的性能:从磁盘盘片外部读取数据的速度比从内部读取数据的速度更快。如果它们是不同的物理磁盘,那么性能差异似乎很可能。此外,一个磁盘可能比另一个磁盘碎片更多,从而导致寻道时间更长和数据传输速率更慢。