0

我在 matlab 中使用 cuda\jacket 遇到了一个非常缓慢的 if 语句响应。(对于找到局部最大值的相同代码,使用简单的 for 循环和 if 条件,5 秒对 0.02 秒)

作为 GPU 编程的新手,我去阅读,当我看到以前的matlab if 语句与 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) & ... 等所有最近的邻居

如果您知道如何解决(或矢量化)这个问题,我将不胜感激......

4

2 回答 2

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 代码以查看是否有其他优化可用(即查看完全删除 if 条件的可能方法)。

编辑

有了新的信息,这里是可以做的。

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
于 2012-08-07T20:03:19.253 回答
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))
于 2012-08-06T18:11:48.807 回答