簡體   English   中英

是否可以加速這個MATLAB腳本?

[英]Is it possible to speed up this MATLAB script?

我遇到了一些性能問題,因此我想加快那些運行緩慢的腳本。 但我對如何加快它們沒有更多的想法。 因為我發現我經常被指數所阻擋。 我發現抽象思維對我來說非常困難。

腳本是

    tic,
    n = 1000;
    d = 500;
    X = rand(n, d);
    R = rand(n, n);
    F = zeros(d, d);
    for i=1:n
        for j=1:n
           F = F + R(i,j)* ((X(i,:)-X(j,:))' * (X(i,:)-X(j,:)));
        end
    end
    toc

討論和解決方案代碼

這里可以建議使用bsxfun方法很少。 另外,繼續閱讀以了解如何在這樣的問題上獲得30x+加速!

方法#1(天真矢量化方法)

為了適應X行之間的兩次減法操作,然后是它們之間的后續逐元素乘法,一個朴素的基於bsxfun的方法將導致一個4D中間數組,它對應於((X(i,:)-X(j,:))' * (X(i,:)-X(j,:))) bsxfun ((X(i,:)-X(j,:))' * (X(i,:)-X(j,:))) 之后,需要將R乘以得到最終輸出F 這是如下所示實現的 -

v1 = bsxfun(@minus,X,permute(X,[3 2 1]));
v2 = bsxfun(@times,permute(v1,[1 3 2]),permute(v1,[1 3 4 2]));
F = reshape(R(:).'*reshape(v2,[],d^2),d,[]);

方法#2(不那么天真的矢量化方法)

前面提到的方法進入4D可能會減慢速度。 因此,您可以通過重新整形將中間數據保留到3D。 這是下一個 -

sub1 = bsxfun(@minus,X,permute(X,[3 2 1]));
sub1_2d = reshape(permute(sub1,[1 3 2]),n^2,[])
mult1 = bsxfun(@times,sub1_2d,permute(sub1_2d,[1 3 2]))
F = reshape(R(:).'*reshape(mult1,[],d^2),d,[])

方法#3(混合方法)

現在,您可以基於方法#2vectorized subtractions + loopy multiplications )制作混合方法。 這種方法的好處在於它使用fast matrix multiplication來執行乘法,並將復雜度從較早的O(n ^ 2)降低到O(n),這應該使其更有效。 感謝@ Dev-iL,提出這個想法! 這是代碼 -

sub1 = bsxfun(@minus,X,permute(X,[3 2 1]));
sub1 = bsxfun(@times,sub1,permute(sqrt(R),[1 3 2]));

F = zeros(d);
for k = 1:size(sub1,3)
    blk = sub1(:,:,k);    
    F = F + blk.'*blk;
end

標桿

比較原始方法與方法#3的基准代碼

%// Parameters
n = 500;
d = 250;
X = rand(n, d);
R = rand(n, n);

%// Warm up tic/toc.
for k = 1:100000
    tic(); elapsed = toc();
end

disp('------------------------------ With Original Approach')
tic
F1 = zeros(d, d);
for i=1:n
    for j=1:n
        F1 = F1 + R(i,j)*((X(i,:)-X(j,:))' * (X(i,:)-X(j,:)));
    end
end
toc, clear F1 i j

disp('------------------------------ With Proposed Approach #3')
tic
sub1 = bsxfun(@minus,X,permute(X,[3 2 1]));
sub1 = bsxfun(@times,sub1,permute(sqrt(R),[1 3 2]));

F = zeros(d);
for k = 1:size(sub1,3)
    blk = sub1(:,:,k);    
    F = F + blk.'*blk;
end
toc

運行時結果

------------------------------ With Original Approach
Elapsed time is 29.728571 seconds.
------------------------------ With Proposed Approach #3
Elapsed time is 0.839726 seconds.

那么,誰准備好了30倍以上的加速!?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM