Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Optimization 使用布尔值计算表达式时的精度问题_Optimization_Cuda_Kernel_Boolean - Fatal编程技术网

Optimization 使用布尔值计算表达式时的精度问题

Optimization 使用布尔值计算表达式时的精度问题,optimization,cuda,kernel,boolean,Optimization,Cuda,Kernel,Boolean,我试图删除代码中的一些if语句,以使其更适合在Cuda内核中使用。if-else语句的格式如下: if(boolean 1) { double1 = expression1; } else if(boolean 2) { double1 = expression2; } else { double1 = expression3; } 我试图删除if语句的尝试如下所示: double1 = (boolean1) * expression1 + (!boolean

我试图删除代码中的一些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语句形式显然效果很好(我得到的答案大致相当)。然而,两者之间有细微的区别。这适用于一个程序,该程序将在同一内核上迭代数千次,以计算材料点的位移。为了进行测试,我只在50个时间步后比较了if语句和no if语句,这就是区别:

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

我已经仔细阅读了代码,分别计算了表达式,发现它们匹配,只有当与布尔表达式结合时,我才发现问题所在。我曾尝试将布尔表达式转换为双倍,但得到了相同的答案。有人知道有没有办法解决这个问题吗?我的目标是加速,所以使用if语句是最后的选择。上面的两个数字都来自我为比较代码而做的两个不同的CPU实现。这不是GPU和CPU计算之间的区别。谢谢你的建议。

你误译了

double1 = (boolean1) * expression1 + 
          (!boolean1 && boolean2) * expression2 +
          !(boolean1 && boolean2) * expression3;
每当
boolean1
boolean2
中的任何一个为false时,添加
expression3
,但是

if(boolean 1) {
  double1 = expression1;
}
else if(boolean 2) {
  double1 = expression2;
}
else {
  double1 = expression3;
}
仅当
boolean1
boolean2
均为false时,才使用
expression3

正确的翻译将使用

+ !(boolean1 || boolean2) * expression3

通过这些变化,您想要实现什么?如果幸运的话,编译器会识别出该习语,并在内部将其转换回原来的形式。如果没有,你会得到劣质的代码。我基本上是用一个表达式替换If-else块,这样我就不会得到发散的线程。我不理解你关于转换回旧形式的评论,什么旧形式?如果你想这样做,写
double1=boolean1?expression1:(boolean2?expression2:expression3
。但是,当您使用
cuobjdump-sass
查看结果代码时,您可能会发现编译器生成的代码与原始条件代码完全相同。不要低估现代优化编译器!以及“s/old/original/”在我的原始版本中(第一个版本)注释。只是想附和@tera所说的内容——即使你已经删除了
if
语句,你仍然有条件代码。编译器将查看有多少条件代码,并通过分支或使用来实现它。这是多么令人震惊的时刻。谢谢!出于教育目的,你可以使用
cuobjdump-sass
查看编译器从替换代码的更正版本生成的代码。将其与原始代码和我建议的替换代码进行比较,您可能会改变对整个练习有用性的看法。