【发布时间】:2015-06-28 14:53:49
【问题描述】:
我目前正在开发 cuda,但我卡在了下面的代码上。该代码最初是用 matlab 编写的,我正在尝试使用 cuda 重写它:
Pv = 0; Nv =0;
[LOOP]
v1 = l(li);
v2 = l(li+1);
if((v1>0) && (v2>0))
Pv = Pv + 1;
elseif((v1<0) && (v2<0))
Nv = Nv +1;
elseif((v1>0) && (v2<0))
r = v1/(v1-v2);
Pv = Pv + r;
Nv = Nv + 1 - r;
elseif((v1<0) && (v2>0))
r = v2/(v2-v1);
Pv = Pv + r;
Nv = Nv + 1 - r;
end
[LOOP END]
但是,在 cuda 架构中,“if”表达式有时很昂贵,我相信有一些方法可以避免使用它,尽管我现在无法弄清楚。
代码的主要目的是计算正区间与负区间的比例,并将它们分别相加。在大多数情况下,v1 和 v2 具有相同的符号,但是一旦它们具有不同的符号,我必须使用一堆“if”甚至可能是“abs()”来处理这种情况。
那么,谁能帮助我用 C 重写代码,同时尽可能少地使用“if”?
【问题讨论】:
-
Pv, Nv, v1, v2有哪些类型?float,double? CUDA 编译器可能使用 if-conversion 来断言代码,或者将这些赋值转换为三元运算符,因此尝试手动将其转换为无分支代码可能是过早的优化。使用cuobjdump --dump-sass检查生成的 SASS 并分析内核以查看分支分歧是否是一个很大的问题会很有用。 -
@njuffa 它们都是浮点变量。我从来没有想过检查二进制代码,如果可能的话我会尝试。