我正在尝试删除代码中的一些if语句,以使其更适合在Cuda内核中使用。 if-else语句具有以下格式:
if(boolean 1) {
double1 = expression1;
}
else if(boolean 2) {
double1 = expression2;
}
else {
double1 = expression3;
}
我尝试删除if语句的方法如下:
double1 = (boolean1) * expression1 +
(!boolean1 && boolean2) * expression2 +
!(boolean1 && boolean2) * expression3;
转换为no-if-statement表单显然效果很好,即我得到的答案就在球场上。但是,存在细微差别。这是一个程序,它将遍历相同的内核数千次,以计算材料点的位移。为了测试,我比较了if语句和&只有50个步骤之后的no-if-statement,这就是区别:
if statements: -2.2900031243(9010440)e-004
no if statements: -2.2900031243(8959510)e-004
我已经逐步完成代码并单独评估表达式,发现它们匹配,只有当我看到问题时才与布尔表达式结合使用。我已经尝试将布尔表达式转换为双打,但是得出了相同的答案。有没有人知道是否有办法解决这个问题?我的目标是加速,所以使用if语句是最后的选择。上面的两个数字来自我用于比较代码的两种不同的CPU实现。这不是GPU和CPU计算之间的差异。我很感激任何建议。
答案 0 :(得分:2)
你有错译,
double1 = (boolean1) * expression1 +
(!boolean1 && boolean2) * expression2 +
!(boolean1 && boolean2) * expression3;
每当expression3
和boolean1
中的任何一个为假时,都会添加boolean2
,但
if(boolean 1) {
double1 = expression1;
}
else if(boolean 2) {
double1 = expression2;
}
else {
double1 = expression3;
}
仅当expression3
和boolean1
的 为假时,才会使用boolean2
。
正确的翻译将使用
+ !(boolean1 || boolean2) * expression3