我试图更好地理解导致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语句测试原始数组的每个索引是否至少更有效率?
编辑:在评论中,我被问到如何知道数组以0还是1开头?为了简单起见,我不再赘述,也不想编辑上面的代码以使其更长,但是在程序开始时我会有一个if语句,该语句说明数组是以0还是1开头。分支会按正确的顺序放置循环。
答案 0 :(得分:0)
基准测试可以判断CPU是否对此类代码进行分支预测。当您创建两个退出条件相当容易预测的循环时,CPU可能可以在那里进行分支预测。