【问题标题】:Why is this MATLAB script taking so long to execute?为什么这个 MATLAB 脚本需要这么长时间才能执行?
【发布时间】:2016-12-24 22:02:06
【问题描述】:

我正在尝试在使用 sum-product 解码时在 BPSK AWGN 通道上模拟 LDPC 码的性能。

为此,我在 MATLAB 中编写了一个函数,该函数遵循in the 34th page of this paper 描述的算法。但是,当我使用我用大尺寸奇偶校验矩阵编写的函数(我需要使用 1012 x 1518 的矩阵)时,程序需要 FOREVER 进行单次迭代(我试图模拟性能通过至少进行 100k 次迭代来获得良好的估计,从而获得该通道中的代码)。我使用的矩阵 H 的密度非常低(每列只有两个 1),所以我希望脚本运行得更快。

我认为可能使用float 表示只有 0 和 1 的矩阵可能是问题所在,但我不确定这是否意味着巨大的变化。此外,如果这些矩阵是布尔值,我将不知道如何执行我在函数中使用的一些操作。

那么有人知道吗?我把我写的函数放在下面。

function y = sum_product(r, H, I_max)

[m , n] = size(H);

I = 0;

for i = 1:n
    for j = 1:m
        if H(j,i) == 1
            M(j,i) = r(i);
        else
            M(j,i) = 0;
        end
    end
end

M = sparse(M);

E = M;

while 1

for j = 1:m
    for i = 1:n
        aux = 1;
        if H(j,i) == 1
            for l = 1:n
                if l~=i & H(j,l) == 1
                    aux = tanh(M(j,l)/2)*aux;
                end
            end
            E(j,i) = log(1+aux)-log(1-aux);
        end
    end
end

for i = 1:n
    aux = 0;
    for j = 1:m
        if H(j,i) == 1
            aux = aux + E(j,i);
        end
    end

    L(i) = aux + r(i);

    z(i) = L(i)<=0;
end

if I == I_max | mod((H*transpose(z)) , 2) == 0
    break;
else
    for i = 1:n
        for j = 1:m
            aux = 0;
            if H(j,i) == 1
                for l = 1:m
                    if l~=j & H(l,i) == 1
                        aux = aux + E(l,i);
                    end
                end
            M(j,i) = aux + r(i);
            end
        end
    end
I = I + 1;
end
end

y = z;

end

【问题讨论】:

  • 什么版本的 MATLAB?重现性能问题的rHI_max 的值是多少?你有没有profiled your code 确定大部分计算时间都花在了哪里?

标签: matlab performance optimization


【解决方案1】:

正如其他答案所述,矢量化通常会加快您的计算速度。这意味着您不必为矩阵的每个元素多次运行相同的函数,而只能为整个矩阵运行一次该函数。如果您更熟悉循环和if else 语句,您可以考虑使用诸如 c++ 之类的语言来达到所需的速度。所以这里是一个向量化的形式;

function z = sum_product(r, H, It_max)
    m  = size(H,1);
    n  = size(H,2);
    M = repmat(r,m,1);
    L = zeros(m,n);
    E = zeros(m,n);
    x = reshape(1:numel(H),m,n).';
    idx1= reshape(x(logical(H')),[],m).';
    idx2= reshape(find(H),[],n);
    for It = 0:It_max
        tn = tanh(M(idx1)/2);
        pr = bsxfun(@rdivide,prod(tn,2),tn);
        E(idx1) = log((1+ pr)./(1-pr));
        sumE = sum(E(idx2));
        L = sumE + r;
        z = L <= 0;
        if all(mod(H * z.',2) == 0)
            break;
        end
        M(idx2) = bsxfun(@plus,bsxfun(@minus,sumE , E(idx2) ),r);
    end
end

【讨论】:

    【解决方案2】:

    问题是你可能不应该使用for-loops,嵌套循环更不用说了,因为 Matlab 是一种解释语言。为了加快速度,请尝试对您的操作进行矢量化,以利用 MATLAB 内置函数的速度。

    【讨论】:

    • 解释与编译在这里不相关。有很多解释语言具有快速循环。随着语言的成熟,MATLAB 中循环与矢量化内置函数的性能差距也在缩小,因此这不再是一个有效的绝对概括性陈述,当然也不能回答这个问题。 OP 应该profile the code 来确定计算时间花在哪里。
    猜你喜欢
    • 2017-09-22
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    相关资源
    最近更新 更多