我试图更好地理解是什么导致分支预测被计算,以及什么不会导致它被计算。
比如说,我有一个包含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语句测试原始数组的每个索引,它至少更有效吗?
编辑:在评论中,有人问我如何知道数组是以0还是1开头?为了简单起见,我忽略了这一点,并且不想编辑上面的代码使其变得更长,但是我会在程序开头使用一个if语句来判断数组是否以0或1开头。然后,这个单一的分支将使循环按正确的顺序运行。