“一个典型的错误-盲目地连续进行所有基准测试”:Andrey Akinshin接受基准测试采访



去年,Andrei Akinshin梦游者)出版了《 Pro .NET Benchmarking》一书:有关基准测试的详细工作,对.NET开发人员和其他领域的IT专家都非常有用。

在发布前还有几个月的时间,我们举行了DotNext 2019 Piter会议,在网上广播中,我们询问了Andrei这本书以及基准测试。从那以后看来,这次采访本来应该已经过时了:他们在未来时态中谈论这本书,现在已经六个月了。但是在过去的六个月中,人类尚未决定采用第99个百分位-因此,对于每个可以使用基准测试的人来说,安德烈(Andrei)的答案仍然具有很多相关性和趣味性。

会表演关于DotNext的未来,主题为``让我们谈论性能分析''-即不是编写基准,而是分析收集的价值。目前,Andrey正在研究数以百计的有关数学统计的文章,以向您介绍最适合现实生活中的性能分析的方法。在书中,也对这种分析给予了关注,在接受采访时,安德烈(Andrey)只是解释了其重要性。因此,在期待新报告的发布时,我们为所有人打开了采访视频,并专门为Habr制作了文字记录本:现在,不仅可以查看,而且可以阅读。


这本书的主要内容


-我们再次欢迎DotNext广播的观众。这次Andrey Akinshin和我们在一起。

- 大家好!

-现在与您有关的主要新闻是一本书的宣布,该书将于9月发行...-

如果一切顺利,它将在6月下旬发行。

在这里,您需要了解截止日期的工作方式。有最极端的情况,在任何情况下都不能违反。在亚马逊上,该书的发行日期约为8月23日。而且,如果您推迟此日期,各种处罚都会取消,亚马逊会感到不高兴。如果这本书出版较早-很好,很好。

因此,我真的希望,如果任何地方都没有问题,那么有可能在六月阅读。因此,八月底是截止日期。您还从事IT工作,因此您了解这些工作原理。

-大多数观众可能已经听说过这本书。但是对于那些不认识的人,让我们从一个关于她的故事开始。

-这本书称为“ Pro .NET Benchmarking”。她来自Apress系列-最近发行Conrad Coconut 的Pro .NET内存管理书的同一本书。萨莎·戈德斯坦(Sasha Goldstein )的“ Pro .NET Performance”出版了 -您可能听说过,它不时在DotNext上播放。在同一系列中是我的书。它是关于如何从头到尾进行基准测试。

从统计开始,我试图涵盖多个方面,其中有单独的一章。这不是我们在大学里教书的方式,我没有一个关于“装进盒子里的球”的例子。专注于基准测试过程中可以使用的方便因素:度量,标准偏差,标准误差,各种置信区间以及如何解释它们。也就是说,我们正在谈论以下内容:如果条件BenchmarkDotNet给您提供了100万个不同的数字,我应该如何处理它们?给出了有关如何解释这些数据并得出结论的实用建议。

例如,有一章是关于CPU约束基准和内存约束基准的。有许多不同的案例研究,并举例说明了如何为3-4行编写基准,同时由于现代Intel处理器的一些微体系结构效应而使自己陷入困境。

还有一章关于性能分析和性能测试。基准测试作为一个单独的实验是不错的,但是许多人希望将基准放在CI上,始终将其驱动到某个服务器上(最好是在同一台服务器上),例如收集数据以赶上性能下降的趋势。因此,有一章介绍了如何使用此类数据并编写不同类型的性能测试(其中很多是不同的)。例如,冷启动,热启动,如何处理图形,如何处理整个数据数组的测试之间的区别是什么。

在过去的DotNext之一中,我发言关于性能分析,他谈到了搜索性能异常的不同方法。退化不是唯一可能出现的问题。例如,基准测试工作一秒钟或十秒钟时,会出现多峰分布。在大型产品(尤其是多线程)中,肯定会出现这种情况,通常情况下它们会隐藏问题。即使不是在相应机器上运行性能测试,而是通常的测试,魔鬼也知道如何“颤抖”并给出大量差异,然后,如果您收集并分析所有这些数据,就会发现很多存在此类问题的测试。

通常,基准测试中有很多非常有趣的任务,我仔细地将它们布置在架子上。但是我尝试尽可能地做到这一点,因此它不仅是一种理论,而且是我可以在生产中使用并在我的产品上使用的一些知识。

标杆管理的精妙之处


-我记得我在某处读过的短语,对于互联网上的任何基准测试结果,您都会发现对该结果的错误解释。您对这句话有多同意?

-绝对同意。关于有效和无效基准的讨论很多,但是如果您从鸟瞰的角度来看,那么如果您以某种方式进行了测量,收集了至少一些性能指标并将它们显示在文件或控制台中,那么这就是具有一定基准的基准从角度来看,这是有效的:某些东西可以度量并显示一些数字。主要问题是如何解释这些数字以及下一步将要做什么。

专注于基准测试主题的人们的第一个错误是,他们将对所有基准进行基准测试而没有问自己“为什么”的问题。好吧,我们进行基准测试,测量-然后呢?确定我们进行基准测试的目的非常重要。

例如,如果我们要提供稳定的工作负载,可以用来评估某些情况下的性能并检测性能下降-这就是一种情况。另一个例子:我们有两个做相同事情的库,我们追求性能,我们想选择最快的一个库-您如何比较?

从解释的角度来看,任何能够做出正确业务决策的人都可以被认为是好的。不一定正确,但是如果成功,那就很好。

而且,我什至在书中还做了一些特别的练习。假设有两种算法,而练习是这样的:首先,您需要制定一个基准测试,以表明第一种算法的速度是第二种算法的10倍,然后是一个显示相反算法的基准。您可以使用源数据,使用环境,将Mono更改为.NET Core或在Linux而不是Windows上运行-有上百万种自定义选项。结论是:如果您打算表明一个程序比另一个程序运行得更快,则很可能有一种方法可以做到。

因此,回到您的问题,很难在有效基准和无效基准之间划清界限,并给出无效的定义(也就是说,应该存在什么以便我们认识到它是不好的)。同样,区别“正确”和“错误”的解释是:您无法完全理解基准测试中发生的事情,无法完全解释所有内部流程(这不是很好,这样做会更好,但是您可以跳过这一部分, (如果非常忙),但同时又要了解图片的外观。而且,如果您成功地做对了(这里的问题又是什么是“正确的”)并做出了正确的业务决策,那么您就做好了。

“如果您只是认真地阅读本书,那么您是否将开始做出“正确”的决定?还是在书的范围之外有很多事情也会影响?

-我认为基准测试是一个只能在实践中掌握的话题。是的,我在书中给出了许多方法,建议和描述陷阱。在基准测试中,存在很多这样的问题,如果您不了解它们,那么在生活中您将永远不会想到它们。但是,如果您了解它们,绝对不能保证您的基准将是正确的。也就是说,这是一个最小的工具包,有助于以某种方式使自己适应该领域。

只有系统地处理此领域,您才能编写正常的基准测试和性能测试。头部中的神经网格训练以读取性能报告-当您查看性能测量过程中获得的分布时,您可以查看汇总表,例如,来自BenchmarkDotNet的汇总表(不仅包括“平均”列,还包括标准偏差)。 ),您可以查看标准误差,其他特征,最小值,最大值,分位数和第99个百分位数。

当您非常非常非常多地查看所有这些内容时,就会累积一定的最低数量,从而使您可以更快地执行绩效投资,并看到没有经验的人(即使他们读了我的书和一百万篇博客文章)也不会看到由于他们没有经验。他们不会看到任何问题,或者将无法立即正确地解释数据。

-在接受Dmitry Nesteruk采访时在此DotNext上(梅萨斯特尔)我们说过,通常IT书籍很快就会过时,但是如果他撰写有关设计模式的文章,那么那里的一切都不会每年改变。基准测试又如何呢?这本书可能也不会很久以前就过时,或者您是否会在两年前写过别的书?

-很难说出单音节的答案。有一定的基础,某些物资不会过时。相同的统计数据:两年前曾考虑过第99个百分位,至今仍被认为是这样,而且人们怀疑两年内什么都不会改变。

顺便说一下,我同时指出:我认为基准测试应该是一门独立的学科。出于某种原因,从历史上看,没有人适当注意系统的测量。好吧,那里有什么?他拿走了它,启动了计时器,关闭了计时器,查看已经过去了多少时间。在这本书中,据初步估计,结果超过600页,每个人都问我:“ 600页可以写什么?”

而且我认为这应该是一门学科,是计算机科学的一个独立领域。这就是“语言不可知论”的方向,通用设备保持正确且不会改变:这是整个人类所达到的目标。这适用于任何运行时,语言,生态系统。但这只是答案的一部分。

另一部分已经与运行时的功能,.NET的功能绑定在一起。现在(在书中对此有很多介绍)、. NET Framework,.NET Core和Mono。性能度量可能会在不同的运行时甚至同一运行时的两个相邻版本上有所不同。如果您使用.NET Core 2.2和即将推出的.NET Core 3.0,则某些工作负载会像白天和黑夜一样有所不同。他们进行了如此出色的优化,以至于最简单的场景被加速了10倍,50倍。

显然,如果您切换到新版本的Core,整个程序将无法以比原来快50倍的速度开始工作,但是通常属于综合基准的单个小片段可能会超频。

发生变化的主要是与所有这些版本相关的变化,出现了新的优化。例如,分层jitting将出现在.NET Core 3.0中。也就是说,运行时首先可以通过代码为该方法快速生成一个简单(但不是很有效)的本机实现。然后,当运行库注意到您多次调用此方法时,它将在后台花费更多时间,并重新生成效率更高的代码。事实是,HotSpot中的Java已经有很多年了,在.NET世界中,它将默认出现在今年下半年的今年发行版中(编者注:我们提醒您,这次采访是在2019年进行的)

对于BenchmarkDotNet来说,正常处理此类情况是一个挑战。在Java世界中,Alexey Shipilev在他的JMH中我很久以前就学会了如何处理它,但是我们仍然必须这样做。在这个问题上,我也与看到运行时的人进行了交流。也就是说,我需要特殊的笔和它们的API才能正确处理所有内容。

这些事情正在改变。很快我们将所有运行时统一在一起,将只有一个.NET5。我认为它将以某种不同的方式重命名,这是一个中间名称。也许不是5,而是6,因为我们已经有一个.NET Core 5.0版本。

-嗯,正如我们从Windows所知,对于Microsoft来说,跳过版本中的数字不是问题。

-是的在DNX时代已经第五个.NET Core有目标框架,现在“ 5.0”已经在很多地方使用了,有很多旧文章。所以我不知道,他们现在将要成为第三版之后的第五版,但是我不仅会错过第四版,而且还会错过第五版,并且马上就会获得第六版。考虑到他们现在想使奇数版本的LTS稳定,而偶数版本不是很稳定的事实,则有可能立即增加7个。

好吧,这是他们的头痛。但重要的是,您需要监视运行时的发展,而这是特定于.NET的部分已过时-并不是很快就过时,而是安静地进行。

我已经在考虑制作第二本书了,所有这些都进行了更新。英特尔处理器也并没有停滞不前,而是在不断发展,出现了新的优化方法,这也需要巧妙地加以处理。Skylake带来了许多令人不愉快的惊喜,在同一BenchmarkDotNet中,做了很多工作来解决棘手的优化问题并获得稳定的结果。

与BenchmarkDotNet和Rider的交互


-显然,使用BenchmarkDotNet库已经为您带来了很多经验,因此合乎逻辑的是,您是撰写有关基准测试主题的书的。随之而来的问题是:这本书是否与BenchmarkDotNet有联系,还是“与工具无关”?

-我想让她与工具无关。关于BenchmarkDotNet,我有一个小节,在案例研究中也以它为例:当我需要显示一些小的微体系结构效果时,我说“这里我们将使用BenchmarkDotNet编写基准”。只是为了避免在书中的每个基准测试中放置一百万条内容,而无处单独编写热身逻辑。我们已经有一个现成的解决方案,可以为我们完成整个基准测试例程,并且我们不再讨论这种方法(我们在开始时就已经讨论过),而是在CPU级别上讨论其效果。

这里有两个用例,其余的我尽量从BenchmarkDotNet中提取。那本书不仅对.NET开发人员有用,而且对Java开发人员也很有用。因为所有常见的机制都可以轻松移植到任何其他平台,所以.NET和BenchmarkDotNet用作说明此概念的工具。

-另一个方向是影响吗?在编写本书的过程中,您最终了解了像这样在BenchmarkDotNet中需要做什么吗?

-是的,我写了各种各样的小筹码,特别是为了将它们写在书中。例如,我已经谈到了对多峰分布的冷检测。

以良好的方式,当您分析基准测试的结果时,您应该始终查看分布,打开图片,研究那里发生的情况。但实际上,没有人这样做。因为如果我有条件地在某种代码基础上运行50个基准,并且我每天更改该代码基础10次,并且每次重新启动全套,那么即使我当然也不会看50张图,我必须这样做懒洋洋。而且,从总体上讲,这是没有意义的,这不是人工任务,而是调整任务。

BenchmarkDotNet具有很酷的算法,可以自动确定分布是多峰分布,并警告用户:“伙计!看图表!这里一切都不好!这是平均值出现在列中的位置,请不要查看它!它与任何内容都不对应,请看图表!”

并且仅在那些不让徒劳的图形分散人们的注意力真正重要的情况下才打印此文件。在那里,一种基于Brendan Gregg 所谓的m值的方法是Netflix的领先性能工程师。

但是他的方法对我来说还不够,因为他使用了基于分布的特殊构造的直方图。也就是说,将直方图馈入输入,考虑n值并由它神奇地确定,我们是否具有多峰分布。以及如何建立直方图,Brendan Gregg没有写!我不得不发明自己的自行车,这种自行车出奇地好用。本书中总结了该算法。

有很多这样的故事。直接写书花了我两年半的时间。总的来说,我已经收集了五年的内容,从我与出版社达成协议的那一年开始,已经有两年半了。在这两年半的时间里,由于有了这本书,图书馆在很多方面都得到了发展,那里已经出现了很多东西。

-很难想象,但是除了本书和BenchmarkDotNet之外,您的生活中还会有Rider的开发工作-而且在那里您可能还会进行基准测试。你能谈谈这个吗?您在Twitter上的冰箱中加热器旁边有一台Macbook的照片,检查它如何影响性能-是工作还是书本,还是两者都用?

-在一起。在骑手我们使用BenchmarkDotNet进行个人绩效投资。就是说,当您需要找出如何在某些对性能有严格要求的代码中编写代码的最佳方式,或者您需要研究在Linux上的Mono和Windows上的.NET Framework方面,我们在代码行为方面的不同之处。我们采用BenchmarkDotNet,设计实验,收集结果,得出结论,制定业务决策,如何编写代码,以便使其在任何地方都能快速运行。然后这个基准被扔掉了。

也就是说,我们没有系统地在CI上运行的BenchmarkDotNet上建立基准。但是,相反,我们还有许多其他工作领域。例如,一种内部工具可从所有测试中收集数字,并在其中查找不同的性能异常,相同的多峰分布,具有较大标准偏差的测试,并将其全部收集到一个仪表板中。

我们已经研究了很长时间但尚未这样做的另一种方法是可靠的性能测试。也就是说,我们要提出一种方法,在其中不可能冻结master分支中的性能下降。

传统的基准测试不是很适合,因为它们非常耗费资源。为了获得正常的统计数据并以某种方式使用它,有必要进行大量的迭代。而当您进行成百上千的性能测试时,如果您按预期运行每个测试30次,那么这对于每个人的每一次早午餐来说,铁都不够。

因此,一方面,我想进行尽可能少的迭代(理想情况下是一次迭代,但是一次很难说出是否退化)。当您没有做错任何事情时,可能发生的最糟糕的事情就是误报,但是系统谈论性能下降,并且不允许您冻结master中的早午餐。如果发生这种情况,他们将向我投掷石块,没有人会使用此系统。

因此,有条件地,如果在一次迭代后怀疑存在性能下降,但没有100%的置信度,则值得进行第二次迭代。在第二秒之后,您可以确定一切正常,只是偶然地发生了一些事情。您可以说,现在我们可以确定性能会下降并禁止前进。您可以说:“不,两次迭代仍然不够,我们需要进行第三次。”等等。

而且在少量迭代(一,二,三)上,标准测试根本不起作用。这是我最喜欢的曼惠特尼测验。当您至少有五次迭代时,它将开始正常工作。但是只有当一切都变得非常糟糕时,我们才能达到第五。因此,有必要开发这样一种启发式方法,使其永远不会产生误报,但同时会以最小可能的迭代次数检测降级存在时的降级。现在,对于程序员工程和数学公式的混合来说,这是一个相当困难的任务。我们还没有完成,但是我们要去做。

关于冰箱中的Macbook,这一切也都可以完成。现在,我做的很多微型项目之一就是热节流模型的研究。情况如下:当受CPU限制的基准测试非常重载硬件时,CPU的温度升高,并且当达到某个阈值时,英特尔处理器或操作系统会说:“是,是!我们过热了!” -并在一段时间内降低频率。然后,例如,获得了2-3次迭代,据推测性能下降是可见的。我们就像:“哦,哦,哦,哦!一切都不好!我们不会举行早午餐。”但是实际上,我们只是性能代理过热了。

有不同的处理方法。我们拥有自己的服务器机房和自己的机架,我们试图在那里提供足够的冷却,以免发生这种热调节。但这并不总是成功。也就是说,我们无法完全冻结特工,他们不会那么多,但我们需要以某种方式进行战斗。

另一个选择是,例如,关闭涡轮增压,以使处理器永远不会超出基本频率。因此,这降低了过热的可能性,因为处理器已经不那么热了。其次,我们获得了一个更稳定的频率(在涡轮增压中,它通常会颤抖很多,而在基本频率处关闭涡轮增压时,它会变得非常笔直,您可以获得更加稳定的结果)。

而且,热节流模型非常不同:首先,很大程度上取决于处理器和所有熨斗的配置,其次取决于操作系统。例如,使用Mac:我们有很多Mac测试,因为有很多用户,他们不希望Rider变慢。并且有一个非常激进的热节流模型。

在最近宣布的新型英特尔处理器上,还有更多的笑话。如果您的温度降至某个特定阈值(例如50度)以下,则该频率可能会跳升,甚至超过常规涡轮增压时的最大频率。也就是说,它们会在低温下执行“有点”动态超频之类的操作。效果一样。我们的代理商仍然是有条件的旧处理器,尚未升级,但是喜欢自己购买所有最新产品的极客可以踏上这一步。

未来


“我必须打扰你,因为时间不多了。”但是对于那些感兴趣的人:您是否打算就此材料撰写博客文章?

-是的,当我收集材料时,那里的一切都很有趣,这是一个非常复杂的热节流模型。例如,Windows上有电源节流功能,可让您节省电池电量甚至更多。当我收集数据时,然后将它们全部合并在博客文章中,甚至在科学文章中,或者将其纳入本书的第二版。

, . — , , .

DotNext 2020 Piter -. , , , . -, , . -, . — .

Source: https://habr.com/ru/post/undefined/


All Articles