【问题标题】:Do loops cause branch predictions循环是否会导致分支预测
【发布时间】:2018-11-30 06:36:05
【问题描述】:

我试图更好地了解导致计算 branch prediction 的原因,以及不计算的原因。

例如,我有一个包含 1 和 0 的数组。我想遍历这个数组,如果它读到 0 做某事,但如果它读到 1 做别的事情。

使用 JavaScript 会如下所示:

var array = [0, 1, 1, 1, 0, 0, 0];

for(i=0; i < array.length; i++){
    if(array[i] == 0){
        // Do The 0 Instruction

    }else{
        // Do The 1 Instruction

    }
}

我知道这将导致进行分支预测,因为程序在从数组中读取数据之前不知道需要采取哪些步骤。

但是,如果我对数组进行预处理以将连续 1 或 0 的数量组合成一个数字会怎样。因此,例如数组将更改为:

var array = [0, 1, 1, 1, 0, 0, 0];
var condensedArray = [1, 3, 3];

现在我可以使用这样的循环,而不是使用 if 语句来分支我的指令:

var condensedArray = [1, 3, 3];

for(i=0; i < condensedArray.length; i+=2){

  for(j=0; j < condensedArray[i]; j++)
    //Do The 0 Instruction

  for(j=0; j < condensedArray[i+1]; j++)
    //Do The 1 Instruction

}

这是否仍会导致分支预测被计算和错过?如果是这样,是否至少比使用 if 语句测试原始数组的每个索引更有效?

编辑: 在 cmets 中,有人问我如何知道数组是以 0 还是 1 开头的?为了简单起见,我把它省略了,不想再编辑上面的代码,但我会在程序的开头有一个 if 语句,说明数组是否以 0 或 1 开头。然后那个分支会以正确的顺序放置循环。

【问题讨论】:

  • 在第一个 for 循环中你怎么会总是 0 情况让我们考虑这个数组 [1,0,0,1,1] 它会失败,第二个问题是当我变成 2 秒循环会抛出异常 ArrayindexOutOfException。
  • @DHARMENDRASINGH 为了简单起见,我把它排除在外,但基本上我会在程序开头有一个 if 语句,说明如果数组以 0 或 1 开头,那么该单个分支将将以下循环按顺序排列。抱歉,我将编辑我的答案以反映这一点。
  • 我没有看到像这样优化的好处。添加更多分支不会提高性能。对数据进行排序肯定会有所帮助,这基本上就是您在第二个示例中尝试做的事情。但是,排序需要时间,所以除非您要重用数据,否则没有意义。
  • @ffhighwind 排序将在客户端运行程序之前完成。这是给客户哪个数组的问题。它如何添加更多分支?这就是我想要弄清楚的。

标签: javascript arrays performance branch-prediction


【解决方案1】:

基准测试可以判断 CPU 是否对此类代码进行分支预测。当您创建两个退出条件相当容易预测的循环时,CPU 可能能够在那里进行分支预测。

【讨论】:

    猜你喜欢
    • 2014-01-25
    • 2015-05-11
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 2013-01-03
    • 1970-01-01
    相关资源
    最近更新 更多