0

我试图在我的代码中删除一些 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 形式显然工作得很好,即我得到的答案在球场上。但是,有细微的差别。这是针对将在相同内核上迭代数千次以计算质点位移的程序。为了进行测试,我仅在 50 个时间步之后比较了 if 语句和 no-if 语句,这就是区别:

if statements:    -2.2900031243(9010440)e-004
no if statements: -2.2900031243(8959510)e-004

我已经单步执行了代码并分别评估了表达式并发现它们匹配,只有在与布尔表达式结合时我才看到问题。我尝试将布尔表达式转换为双打,但得到了相同的答案。有没有人知道是否有办法解决这个问题?我的目标是加速,所以使用 if 语句是最后的手段。上面的两个数字都来自我用来比较代码的两个不同的 CPU 实现。这不是 GPU 和 CPU 计算之间的区别。我很感激任何建议。

4

1 回答 1

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
于 2013-04-22T18:04:44.127 回答