嵌套for循环非常慢在MATLAB(preallocated) [英] Nested for loops extremely slow in MATLAB (preallocated)

查看:1932
本文介绍了嵌套for循环非常慢在MATLAB(preallocated)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想学习MATLAB和我遇到的第一个问题是猜测,从图像序列具有静态照相机和移动物体的背景。一开始我只想做随着时间的推移像素的均值或中位数,所以它的只是一个单一的功能,我想申请到4维数组

I am trying to learn MATLAB and one of the first problems I encountered was to guess the background from an image sequence with a static camera and moving objects. For a start I just want to do a mean or median on pixels over time, so it's just a single function I would like to apply to one of the rows of the 4 dimensional array.

我已经载入我的RGB图像在4维数组的尺寸如下:

I have loaded my RGB images in a 4 dimensional array with the following dimensions:

uint8 [ num_images, width, height, RGB ]

下面是我写的功能,其中包括4嵌套循环。我使用 preallocation ,但仍然显得十分缓慢。在C ++中,我相信这个功能可以运行至少10倍至20倍的速度更快,而且我认为在CUDA它可以实时的实际运行。在MATLAB它需要用4个嵌套循环约20秒。我的堆栈100的图像与640x480x3尺寸。

Here is the function I wrote which includes 4 nested loops. I use preallocation but still, it is extremely slow. In C++ I believe this function could run at least 10x-20x faster, and I think on CUDA it could actually run in real time. In MATLAB it takes about 20 seconds with the 4 nested loops. My stack is 100 images with 640x480x3 dimensions.

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

你能告诉我如何使这个code更快?我试图用某种方式将数据直接从只使用索引数组越来越实验和它似乎更快。它完成在3秒与20秒,所以这是一个7倍的性能差异,只是写一个小功能。

Could you tell me how to make this code much faster? I have tried experimenting with somehow getting the data directly from the array using only the indexes and it seems MUCH faster. It completes in 3 seconds vs. 20 seconds, so that’s a 7x performance difference, just by writing a smaller function.

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个嵌套循环里面。

So now I don't understand if MATLAB could be this fast then why is the nested loop version so slow? I am not making any dynamic resizing and MATLAB must be running the same 4 nested loops inside.

为什么会出现这种情况?

有没有什么办法可以使嵌套循环跑得快,像它会在C ++中自然而然地发生?

Is there any way to make nested loops run fast, like it would happen naturally in C++?

或者我应该习惯了MATLAB编程的想法,在这个疯狂的一行语句的方式来获得最佳的性能?

Or should I get used to the idea of programming MATLAB in this crazy one line statements way to get optimal performance?

更新

感谢您对所有伟大的答案,现在我明白了很多。我原来的code。与栈(:, 1:尺寸(堆栈,2),1:尺寸(堆栈,3),1:3))没任何意义,这是完全一样的,我只是用第一维其工作范围的中位数的默认选项幸运的。

Thank you for all the great answers, now I understand a lot more. My original code with stack(:, 1:size(stack,2), 1:size(stack,3), 1:3 )) didn't make any sense, it is exactly the same as stack, I was just lucky with median's default option of using the 1st dimension for its working range.

我觉得这是更好地问如何写在另一个问题一个有效的问题,所以我问在这里:

I think it's better to ask how to write an efficient question in an other question, so I asked it here:

如何写MATLAB矢量功能

推荐答案

如果我明白你的问题,你问为什么Matlab是用于矩阵运算比过程编程调用更快。答案很简单,就是这就是它如何设计。如果你真的想知道是什么使这样的说法,你可以读<一个href=\"http://www.mathworks.com/company/newsletters/news_notes/clevescorner/winter2000.cleve.html\">this从Matlab的网站通讯,其中讨论了一些基本技术,但你可能不会得到一个伟大的答案,因为该软件是专有的。我也发现了一些相关网页通过google搜索简单和<一个href=\"http://www.mathworks.com/company/newsletters/news_notes/clevescorner/winter2000.cleve.html\">this老这么问
 也似乎解决您的问题。

If I understand your question, you're asking why Matlab is faster for matrix operations than for procedural programming calls. The answer is simply that that's how it's designed. If you really want to know what makes it that way, you can read this newsletter from Matlab's website which discusses some of the underlying technology, but you probably won't get a great answer, as the software is proprietary. I also found some relevant pages by simply googling, and this old SO question also seems to address your question.

这篇关于嵌套for循环非常慢在MATLAB(preallocated)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆