科学软件与其他软件没有太大区别,就如何知道需要调整的内容而言。
我使用的方法是随机暂停。这是它为我找到的一些加速方法:
如果将很大一部分时间花费在诸如log
和等函数上exp
,那么我将看到这些函数的自变量是什么,取决于它们从中被调用的点。通常,它们会使用相同的参数反复调用。如果是这样,则记忆会产生巨大的加速因素。
如果我使用的是BLAS或LAPACK函数,则可能会发现例程中花费了大量时间来复制数组,乘以矩阵,choleski变换等。
如果我可以扩展后者:矩阵乘法例程DGEMM调用LSAME来解码其字符参数。查看被认为是“良好”的剖析时间(唯一值得关注的统计数据)可能会显示DGEMM使用总时间的某些百分比(例如80%)和LSAME使用总时间的某些百分比(例如50%)。看看前者,您可能会想说“必须对其进行大量优化,所以对此我无能为力”。看着后者,您会很想说:“嗯?这是怎么回事?那只是个小小的例行程序。此探查器一定是错误的!”
没错,只是没有告诉您您需要知道什么。随机暂停显示的是DGEMM在堆栈样本中占80%,而LSAME在堆栈样本中占50%。(您不需要太多示例来检测到这一点。通常10个示例就足够了。)此外,在许多示例中,DGEMM正在从几行不同的代码行调用LSAME。
所以现在您知道了为什么这两个例程都花那么多的包容时间。你也知道在你的代码,他们正在从所谓的花这么长的时间。这就是为什么我使用随机暂停并剖析探查器的黄疸病的原因,无论它们的制作水平如何。他们对获取测量值比告诉您发生的事情更感兴趣。
可以很容易地假设数学库例程已被优化到n级,但实际上它们已经被优化以可用于多种用途。您需要查看实际发生的情况,而不是容易理解的情况。
添加:因此,请回答您的最后两个问题:
首先要尝试的最重要的事情是什么?
拿10-20个堆栈样本,不要只是汇总它们,了解每个样本在告诉您什么。首先,最后和之间进行此操作。(年轻的天行者没有“尝试”。)
我怎么知道我可以获得多少性能?
Xβ(小号+ 1 ,(ñ - 小号)+ 1 )s1 /(1 − x )n = 10n1/(1−x)n=10s=5x为0.5,加速比为2。这是分布:
如果您不愿冒险,则是的,小于0.1的可能性很小(.03%),对于加速比小于11% 。但是,对于大于10的加速比,等于0.9的概率是相等的!如果您按程序速度成正比地赚钱,那可不是什么好事。xx
正如我之前向您指出的,您可以重复执行整个过程,直到不再执行为止,并且复合加速比可能会很大。
添加:针对Pedro对误报的关注,让我尝试构建一个可能会出现误报的示例。除非我们两次或多次看到潜在的问题,否则我们不会采取任何行动,因此,我们期望在尽可能短的时间内看到问题,尤其是在样本总数很大时,会出现误报。假设我们抽取了20个样本,并且看到了两次。估计它的成本是总执行时间(即分发方式)的10%。(分布的平均值较高-为。)下图中的下部曲线是其分布:(s+1)/(n+2)=3/22=13.6%
考虑一下我们是否抽取了多达40个样本(比我一次采样的样本还要多),却只发现其中两个样本有问题。如较高的曲线所示,该问题的估计成本(模式)为5%。
什么是“误报”?如果您解决了一个问题,却发现收益比预期的要小,您为解决该问题感到后悔。曲线显示(如果问题是“小”的话),尽管增益可能小于显示它的样本比例,但平均而言它将更大。
风险要严重得多-“假阴性”。就是说有问题,但是没有找到。(造成这种情况的是“确认偏见”,在这种情况下,缺乏证据往往会被视为缺乏证据。)
使用事件探查器(一个不错的工具)得到的结果是,您可以得到更精确的度量(因此,误报的可能性会降低),而对于问题实际所在的信息的精确度却要低得多(因此,发现并获得问题的机会就会减少)任何收益)。这限制了可以实现的整体速度。
我鼓励分析器用户报告他们实际在实践中获得的加速因素。
还有另一点要提到。佩德罗关于误报的问题。
他提到在高度优化的代码中发现小问题时可能会遇到困难。(对我来说,一个小问题是占总时间的5%或更少。)
由于完全有可能构建一个除5%之外完全最佳的程序,因此只能凭经验解决此问题,如此答案所示。从经验中得出的结论是这样的:
如所写,程序通常包含多个优化机会。(我们可以称它们为“问题”,但它们通常是非常好的代码,仅能进行相当大的改进。)此图说明了一个人工程序,该程序花费一些时间(例如100s),其中包含问题A,B,C, ...发现并修复后,可节省原始100s的30%,21%等。
请注意,问题F花费了原始时间的5%,因此它“很小”,并且在没有40个或更多样本的情况下很难找到。
但是,前10个样本很容易发现问题A。**修复该问题后,程序仅花费70秒钟,加速比为100/70 = 1.43x。这不仅使程序更快,而且还以该比例放大了其余问题所占的百分比。例如,问题B最初花费21s,占总数的21%,但是在删除问题A之后,B花费了70s中的21s,即30%,因此在重复整个过程时更容易发现。
一旦重复执行该过程五次,现在执行时间为16.8s,其中问题F为30%,而不是5%,因此10个样本很容易找到它。
这就是重点。根据经验,程序包含一系列具有大小分布的问题,找到并解决的任何问题使查找剩余的问题变得更加容易。为了做到这一点,没有一个问题可以跳过,因为如果有的话,它们就坐在那儿花时间,限制了总的加速,并且无法放大剩余的问题。
因此,找到隐藏的问题非常重要。
如果问题A到F被发现并解决,则加速比为100 / 11.8 = 8.5倍。如果错过了其中之一,例如D,则加速仅为100 /(11.8 + 10.3)= 4.5倍。
这就是假阴性所付出的代价。
因此,当探查器说“这里似乎没有什么大问题”(即,好的编码器,这实际上是最佳代码)时,也许是正确的,也许不是。(错误的否定。)您不确定是否要解决更多问题以提高速度,除非您尝试其他分析方法并发现有问题。根据我的经验,概要分析方法不需要摘要中的大量样本,而需要少量样本,在这些样本中,对每个样本的了解都足够透彻,可以识别出进行优化的任何机会。
**至少需要2次命中才能找到问题,除非一个人事先知道有一个(近)无限循环。(红色刻度表示10个随机样本);当问题为30%时,获得2个或更多匹配的平均样本数为(负二项分布)。10个样本以85%的概率找到它,20个样本-99.2%(二项式分布)。要获得发现问题的可能性,请在R中进行评估,例如:。2/0.3=6.671 - pbinom(1, numberOfSamples, sizeOfProblem)
1 - pbinom(1, 20, 0.3) = 0.9923627
增加:节省的时间遵循Beta分布,其中是样本数,是显示问题的数。但是,加速比等于(假设所有均被保存),了解的分布将很有趣。事实证明,遵循BetaPrime分布。我用200万个样本对其进行了模拟,得出了以下行为:xβ(s+1,(n−s)+1)nsy1/(1−x)xyy−1
distribution of speedup
ratio y
s, n 5%-ile 95%-ile mean
2, 2 1.58 59.30 32.36
2, 3 1.33 10.25 4.00
2, 4 1.23 5.28 2.50
2, 5 1.18 3.69 2.00
2,10 1.09 1.89 1.37
2,20 1.04 1.37 1.17
2,40 1.02 1.17 1.08
3, 3 1.90 78.34 42.94
3, 4 1.52 13.10 5.00
3, 5 1.37 6.53 3.00
3,10 1.16 2.29 1.57
3,20 1.07 1.49 1.24
3,40 1.04 1.22 1.11
4, 4 2.22 98.02 52.36
4, 5 1.72 15.95 6.00
4,10 1.25 2.86 1.83
4,20 1.11 1.62 1.31
4,40 1.05 1.26 1.14
5, 5 2.54 117.27 64.29
5,10 1.37 3.69 2.20
5,20 1.15 1.78 1.40
5,40 1.07 1.31 1.17
前两列给出了加速比的90%置信区间。除了的情况以外,平均加速比等于。在那种情况下,它是不确定的,实际上,随着我增加模拟值的数量,经验均值也会增加。小号= Ñ ÿ(n+1)/(n−s)s=ny
这是5个,4个,3个和2个样本中2个匹配项的加速因子及其均值分布的图。例如,如果抽取了3个样本,并且其中有2个碰到一个问题,并且可以消除该问题,则平均加速因子将是4倍。如果仅在2个样本中看到2个命中,则平均加速速度是不确定的-从概念上讲,因为无限循环的程序以非零概率存在!