一些函数使用分支预测系统,该系统允许对某些数据结构进行更快的计算,例如,在包含if语句函数的循环中使用排序后的数据比处理数据更快,而数据是未排序的(有关分支预测的更多信息,请参阅以下精彩文章:为什么处理排序后的数组比处理未排序的数组更快?)。
我的问题很简单:高级编程语言,如C、Python、MATLAB、R等,是否使用马尔可夫链预测来提高某些计算的速度
我不是专家,我才刚刚开始了解马尔可夫链,但在我看来,每一个代码,主要是包含循环的代码,都有一些时间上可预测的随机事件,可以用来加快计算速度。
示例是应用于包含1到200之间整数的矩阵的函数,其中90%的值低于100,即2位数字。根据x或y位整数的概率自动"预分配"一定数量的比特似乎可以提高性能。
分支预测就是这样工作的吗?这是否适用于任何计算?
关于BigInteger
从理论上讲,如果计算整数乘法实际上是比特大小的递增函数,那么这是正确的。也就是说,if整数乘法被实现为带有if语句的循环。然而,32位整数的计算成本将与当前64位CPU上的16位整数或64位整数"相同",因为它们将使用硬件中实现的相同加法器门。在性能32位与64位算术中进行了更深入的讨论
相反,如果您手动存储这些部分大小的值(例如位字段、位向量),您将产生额外的开销。
假设现在我们讨论的是非常大的整数,比如java.math.BigInteger
。然后,您正确地说,您可以通过预先分配所述位数来获得性能优势,而不是在执行操作时从1个单位("数字")开始并创建新的"数字"。看看BigInteger.multiply()
的OpenJDK实现就知道了。这正是他们在multiply
方法中所做的。在某些方面,这个想法也与MATLAB的预分配性能提示有关。当您可以轻松地预分配数组时,不要在OutOfBounds
上进行不必要的分支。
在实践中
现在直接回答你的问题,语言是否利用了马尔可夫链,我相信不是。我所见过的任何语言源(或引擎)都没有维护真正的马尔可夫链。大多数高级语言在其上下文中都是通用的,因此状态预测会给任何类型的计算增加相当大的开销。回到java.math.BigInteger
的例子,只分配数字的和几乎总是比使用存储状态的预测机制更快。结果可能会节省内存,但对性能不利。CPU本身依赖于状态机(可以被认为是马尔可夫链)来执行预测优化,但这是因为它可以在没有明显成本损失的情况下进行优化(请参阅关于分支预测的wiki或java硬件阵列预取的示例)。
也就是说,时间可预测事件的想法是提高总体性能的关键,需要加以利用;它不限于分支预测。数据的组织对性能至关重要。示例包括.NET中的生成垃圾收集、Particle FX中的粒子高效管理和Web服务器预测预取。最后一个实际上利用了一个马尔可夫预测器来确定作为用户日志的函数要预取到缓存中的页面。在智能数据组织的游戏引擎和运行时实现中,可以找到许多其他例子,以击败分支预测或完全跳过它!
tldr
在实际开发中,大多数优化都依赖于对数据进行简化假设,而不是应用马尔可夫预测器。因此,如果您希望利用分支预测,请了解您的数据并将其组织好。这将改善你的预测,或者让你完全跳过它。使用预测器可能会花费更多的开发和执行时间。如果您仍然觉得预测器可能会有所帮助,请维护一个简单的状态机,并将其与天真的解决方案进行比较。