简体   繁体   English

如何加速这个matlab循环

[英]How to speed-up this matlab loops

I hope you can help me out here, I have a speed problem in matlab with the following code: 我希望你能在这里帮助我,我在matlab中遇到速度问题,代码如下:

%Example Definition
bf = 80;
sam = 10000;
dim = 300;
a = rand(bf, sam, dim);
T = rand(bf, sam, dim);
x = repmat(rand(1, sam, dim), [bf 1 1]);

%Calculation
E = zeros(size(T, ndims(T)));
dist = zeros(bf, sam);
a = repmat( a, [ 1 1 dim ]);
for i = 1:dim
    for j = 1:dim
        dist = x(:,:,j) .* T(:,:,i);
         E(i,j) = sum(sum(a(:,:,i) .* (0.5 * dist), 2), 1);
    end        
end

These 3 diminsional arrays are quite big (like 80x10000x300), so that there is a high computation time to calculate this 'E' matrix. 这3个diminsional数组相当大(如80x10000x300),因此计算这个'E'矩阵的计算时间很长。 I've already tried to vectorize it, but i have no a good idea how to do that without going into the memory limit (16 GB). 我已经尝试对它进行矢量化,但我不知道如何在不进入内存限制(16 GB)的情况下进行操作。

Any idea how to speed this up ? 知道如何加快速度吗?

I don't see why it should be more than 16GB. 我不明白为什么它应该超过16GB。

You store each pixel as 8B. 您将每个像素存储为8B。 80*10K*300=240M, so each matrix is close to 2GB. 80 * 10K * 300 = 240M,因此每个矩阵接近2GB。 You have for matrices, in total 8GB. 你有矩阵,总共8GB。

Your code is quite efficient, one simple suggestion to decrease memory usage is make everything single ; 你的代码非常有效,减少内存使用的一个简单建议是使一切都single ; ie single(zeros(size(T))) single(zeros(size(T)))

Another suggestion is if you are using more matrices, clear variables when you are done. 另一个建议是,如果您使用更多矩阵,请在完成后clear变量。

Also, don't create dist variable, it is used only once. 另外,不要创建dist变量,它只使用一次。

First of all, using i and j for loops slow things down. 首先,使用ij for循环会降低速度。 See: Using i and j as variables in Matlab 请参阅: 在Matlab中使用i和j作为变量

The out-of-memory problem occurs in a = repmat( a, [ 1 1 dim ]); 内存不足问题发生在a = repmat( a, [ 1 1 dim ]); which expands a by bf x sam x dim times. 它扩展a bf x sam x dim times。 However the only place you access a is a(:,:,ii) and ii goes from 1 to dim . 但是,您访问a的唯一地方是a(:,:,ii)ii1变为dim Therefore in the 300x300 elements in the 3rd dimension, only the first 300 are used. 因此,在第三维中的300x300元素中,仅使用前300个元素。

One possible answer: You don't need to repmat and leave a as-is. 一个可能的答案:你不需要repmat并留下a原样。

Another possible answer: a = repmat(rand(bf, sam, 1), [ 1 1 dim ]); 另一个可能的答案: a = repmat(rand(bf, sam, 1), [ 1 1 dim ]);

If you reshape 3D matrices to 2D matrices,nested loop will be converted to a matrix multiplication: 如果将3D矩阵重塑为2D矩阵,嵌套循环将转换为矩阵乘法:

x = reshape(x,[],dim).';
a = reshape(a,[],dim);
T = reshape(T,[],dim);
E = x * (a.*T*.5);

Sometimes just updating your nested loop from the following 有时只是从以下更新嵌套循环

for i=1:m
    for j=1:n
        out(i,j) = something;
    end
end

to

for j=1:n
    for i=1:m
        out(i,j) = something;         %first rows fill
    end
end

would improve the performance significantly: 会显着改善性能:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM