MATLAB 中的嵌套 for 循环非常慢(预分配)

2024-03-30

我正在尝试学习 MATLAB,遇到的第一个问题是从静态相机和移动物体的图像序列中猜测背景。首先,我只想对一段时间内的像素进行平均值或中位数,所以它是我想将一个函数应用于 4 维数组的其中一行.

我已将 RGB 图像加载到具有以下尺寸的 4 维数组中:

uint8 [ num_images, width, height, RGB ]

这是我编写的函数,其中包含 4 个嵌套循环。我用预分配但仍然非常慢。在 C++ 中,我相信这个函数的运行速度至少可以快 10 倍到 20 倍,而且我认为在 CUDA 上它实际上可以实时运行。在 MATLAB 中,4 个嵌套循环大约需要 20 秒。我的堆栈有 100 张尺寸为 640x480x3 的图像。

function background = calc_background(stack)
tic;

si = size(stack,1);
sy = size(stack,2);
sx = size(stack,3);
sc = size(stack,4);

background = zeros(sy,sx,sc);
A = zeros(si,1);

for x = 1:sx
    for y = 1:sy
        for c = 1:sc
            for i = 1:si
                A(i) = stack(i,y,x,c);
            end
            background(y,x,c) = median(A);
        end
    end
end

background = uint8(background);

disp(toc);
end

你能告诉我如何使这段代码更快吗?我尝试过以某种方式仅使用索引直接从数组获取数据进行实验,看起来速度要快得多。它完成于3 秒与 20 秒,因此仅通过编写更小的函数即可实现 7 倍的性能差异。

function background = calc_background2(stack)
    tic;

    % bad code, confusing
    % background = uint8(squeeze(median(stack(:, 1:size(stack,2), 1:size(stack,3), 1:3 ))));

    % good code (credits: Laurent)
    background=uint8((squeeze(median(stack,1)));

    disp(toc);
end

所以现在我不明白如果 MATLAB 可以这么快,那么为什么嵌套循环版本这么慢?我没有进行任何动态调整大小,并且 MATLAB 必须在内部运行相同的 4 个嵌套循环。

为什么会发生这种情况?

有没有办法让嵌套循环运行得更快,就像在 C++ 中自然发生的那样?

或者我应该习惯用这种疯狂的一行语句方式对 MATLAB 进行编程以获得最佳性能吗?

Update

谢谢大家的精彩回答,现在我明白了很多。我的原始代码与stack(:, 1:size(stack,2), 1:size(stack,3), 1:3 ))没有任何意义,它完全一样stack,我很幸运使用中位数的默认选项,即使用第一维作为其工作范围。

我认为如何写一个高效的问题最好在另一个问题中问,所以我在这里问:

如何在 MATLAB 中编写向量化函数 https://stackoverflow.com/q/7814220/518169


如果我理解你的问题,你会问为什么 Matlab 的矩阵运算比程序编程调用更快。答案很简单这就是它的设计方式 http://www.mathworks.com/help/techdoc/matlab_prog/f8-784135.html#br8fs0d-1。如果你真的想知道是什么造成了这种情况,你可以阅读此新闻稿来自 Matlab 网站 http://www.mathworks.com/company/newsletters/news_notes/clevescorner/winter2000.cleve.html其中讨论了一些底层技术,但您可能不会得到很好的答案,因为该软件是专有的。我还发现了一些相关页面 http://web.cecs.pdx.edu/~gerry/MATLAB/programming/performance.html#vectorize通过简单的谷歌搜索,并且这个老问题 http://www.mathworks.com/company/newsletters/news_notes/clevescorner/winter2000.cleve.html似乎也解决了你的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MATLAB 中的嵌套 for 循环非常慢(预分配) 的相关文章

随机推荐