我在matlab中使用cuda \ jacket遇到了一个非常慢的if语句响应。 (对于找到局部最大值的相同代码,使用简单的for循环和if条件,为5秒vs 0.02秒)
刚接触GPU编程,我去阅读,当我看到之前的matlab if statements with CUDA SO讨论时,我觉得缺少了一些东西。 您不需要使用cuda知道向量化代码更好。但是,在某些情况下,您仍需要使用if语句。 例如,我想找出2D图像的像素(比如m(a,b))是否是其8个最近邻居的局部最大值。在matlab中,一种简单的方法是在if语句中使用8个逻辑条件:
如果m(a,b)> m(a-1,b-1)& m(a,b)>(a,b-1)& m(a,b)>(a + 1,b-1)& ......等所有最近邻居
如果你知道如何解决(或矢量化)这个......我很感激。
答案 0 :(得分:2)
使用多个“if”语句(或任何其他条件语句)的问题在于,对于每个语句,结果都是从gpu复制到主机,这可能代价很高。
最简单的方法是以下列方式进行矢量化。
window = m(a-1:a+1, b-1:b+1);
if all(window(:) <= m(a,b))
% do something
end
如果您可以显示if / else条件正在执行的操作,则可以进一步优化。即请发布if / else代码以查看是否有其他优化可用(例如,如果完全符合条件,请查看删除的可能方法。)
修改强>
有了新信息,可以采取以下措施。
for j = 1:length(y)
a = x(j);
b = y(j);
window = d(a-1:a+1, b-1:b+1);
condition = all(window(:) <= d(a,b));
M(a, b) = condition + ~condition * M(a,b);
end
您可以使用gfor循环使其更快。
gfor j = 1:length(y)
a = x(j);
b = y(j);
window = d(a-1:a+1, b-1:b+1);
condition = all(window(:) <= d(a,b));
M(a, b) = condition + ~condition * M(a,b);
gend
答案 1 :(得分:1)
使用内置功能
最简单的已经优化的方法可能是使用imregionalmax
函数
maxinI = imregionalmax(I, CONN);
其中CONN
是所需的连接(在您的情况下为8)。
但请注意,imregionalmax
是图像处理工具箱的一部分。
使用max
功能
如果您正在尝试查看是否只有一个像素是其邻居的局部最大值,您可能会执行类似
的操作if m(a,b) == max(max(m( (a-1) : (a+1), (b-1) : (b+1))))
或许不是采取两个max
,在某些情况下重塑可能会更快,
if m(a,b) == max(reshape (m( (a-1) : (a+1), (b-1) : (b+1)), 9,1) )
没有max
功能
最后,如果你想完全避免使用max
功能,这种功能也可以采用比你目前更加矢量化的形式,即
if all(reshape( m(a,b) >= m( (a-1) : (a+1), (b-1) : (b+1)), 9,1))