设置局部变量时删除分支
Removing branches when setting local variables
哪个代码效率更高:
例程A
local int a[5];
bool condition;
...
a[0] = 0;
if (condition) {
a[0] = 1;
}
或例程B
local int a[5];
bool condition;
....
a[0] = 0;
a[0] = select(a[0], 1, condition);
第二个清单删除了分支,但是如果条件为假,select 语句可能会访问本地内存两次。希望如果条件为假,编译器将执行空操作。
在低级代码和目标机器之间有一个编译器,它和编译器正在编译的目标机器将最终确定要生成的汇编代码。
例如你不能说 'removing the if statement gets rid of the branch' 之类的话,如果编译器决定使用比较和设置指令而不是比较分支后跟移动怎么办?
如果条件始终为假,则代码将被视为死代码,编译器可能会决定不放置任何内容而不是空操作。
如果你成功地生成了程序A和程序B对应的汇编代码,并且只有目标机器的指令成本得到table,你才可以谈论机器代码效率。编译器通常会在其中嵌入这样的 table 以尝试选择最合适的 table 指令组合。
select 看起来它是为向量设计的,而不仅仅是单个值。最有可能的是,它可以使用对数组进行操作的 SIMP 指令,而不是像我们手头的那样只对单个值进行操作。参见 OpenCL built-in function 'select'
哪个代码效率更高:
例程A
local int a[5];
bool condition;
...
a[0] = 0;
if (condition) {
a[0] = 1;
}
或例程B
local int a[5];
bool condition;
....
a[0] = 0;
a[0] = select(a[0], 1, condition);
第二个清单删除了分支,但是如果条件为假,select 语句可能会访问本地内存两次。希望如果条件为假,编译器将执行空操作。
在低级代码和目标机器之间有一个编译器,它和编译器正在编译的目标机器将最终确定要生成的汇编代码。
例如你不能说 'removing the if statement gets rid of the branch' 之类的话,如果编译器决定使用比较和设置指令而不是比较分支后跟移动怎么办?
如果条件始终为假,则代码将被视为死代码,编译器可能会决定不放置任何内容而不是空操作。
如果你成功地生成了程序A和程序B对应的汇编代码,并且只有目标机器的指令成本得到table,你才可以谈论机器代码效率。编译器通常会在其中嵌入这样的 table 以尝试选择最合适的 table 指令组合。
select 看起来它是为向量设计的,而不仅仅是单个值。最有可能的是,它可以使用对数组进行操作的 SIMP 指令,而不是像我们手头的那样只对单个值进行操作。参见 OpenCL built-in function 'select'