簡體   English   中英

是什么讓 MATLAB 對向量的操作如此之快?

[英]What makes MATLAB operations on vectors so fast?

我必須編寫一些 MATLAB 代碼,並且在某些時候我必須應用 function 我將元素寫入向量。 我考慮了兩種不同的方法:

  1. 循環遍歷向量
  2. 使用 MATLAB 元素操作

就我而言,我有一個 function group ,定義如下:

function [g] = group(n, elm_per_group, n_groups)
    g = mod(n, n_groups);
    g(g > elm_per_group) = -1;
end

所以案例#1就像:

N = 1e4;
v = (1:N)';
w = zeros(1, N);
for i = 1 : N
    w(i) = group(v(i), elm_per_group, n_groups);
end

案例#2:

N = 1e4;
v = (1:N)';
w = group(v(:), elm_per_group, n_groups);

當然,除了示例之外,它絕對沒有優化到這樣做。

我在這里這里發現了非常有趣的東西,但我仍然無法理解 MATLAB 使用什么機制來加速計算,給定任意 function,它甚至可能包括隨機性或具有某種需要對每個元素進行特定計算的特性的向量。

我已經有兩個想法可以解釋,對我來說,部分差異:

  1. 由於 MATLAB 索引非常慢,因此循環不是到達向量中每個元素的有效方法
  2. 分析器告訴當循環向量時, group function 已被調用N次,而在使用內置 MATLAB 時只調用一次。 我希望至少可以縮短管理堆棧和 function 調用的時間。

我不相信這兩個 arguments 足以解釋這兩種方法之間的差距。 給出一些數字,案例 #1 需要 7.2 毫秒,案例 #2 需要 0.84 毫秒。

那么,MATLAB 使用哪些附加機制來加快向量元素上相同 function 的N倍計算?

(注意:請報告拼寫錯誤,以便我更正。)

編輯 1:將名稱group更改為g以避免名稱沖突。

編輯 2:修改group function 使其不那么糟糕並且實際工作。

MATLAB 循環非常快。 事實上,即使是向量計算也很少比循環快。 問題是(正如評論中提到的@Cris Luengo)調用(自寫)函數。 我在這里構建了一個小例子(並修復了代碼中的一些問題):

elm_per_group = 20;
n_groups = 10;
N = 1e7;
v = (1:N).';


%% function call
tic % start timing
% allocate memory
w1 = zeros(N,1);
% loop
for i = 1:N
    w1(i) = group(v(i), elm_per_group, n_groups);
end
toc % end timing


%% vectorwise
tic % start timing
w2 = group(v, elm_per_group, n_groups);
toc % end timing

%% direct looping
tic % start timing
% allocate memory
w3 = zeros(N,1);
% loop
for i = 1:N
    n = v(i);
    g = mod(n, elm_per_group);
    if g > n_groups
        w3(i) = -1;
    else
        w3(i) = g;
    end
end
toc % end timing


%% function call 2 (short-cut)
tic % start timing
% allocate memory
w4 = zeros(N,1);
% loop
for i = 1:N
    w4(i) = group2(v(i), elm_per_group, n_groups);
end
toc % end timing


%% check output
% if this assertion fails, not all results are the same!
assert( ~(any(w1-w2) || any(w1-w3) || any(w1-w4)) )



%% local function
function [g] = group(n, elm_per_group, n_groups)
    g = mod(n, elm_per_group);
    g( g > n_groups ) = -1;
end
function [g] = group2(n, elm_per_group, n_groups)
    g = mod(n, elm_per_group);
    if g > n_groups
        g = -1;
    end
end

Output

Elapsed time is 7.697662 seconds. % function call
Elapsed time is 0.463303 seconds. % vectorwise
Elapsed time is 0.669406 seconds. % direct looping
Elapsed time is 0.913067 seconds. % function call 2 (short-cut)

毫不奇怪,我們觀察到(正如您所做的那樣)您的函數循環非常慢,並且向量式公式(我必須修復您的代碼)要快得多。 為什么會這樣?

我們可以從另外兩個示例中看到,調用 function 會產生 30% 的開銷,但使用if -case 可以有效地節省您的時間,因為它可以避免索引和分配新值。 它是您代碼中的快捷方式

這些都是細節,我們在這里討論 10.000.000 次調用的毫秒數。 但要傳達的信息是,除非您在使用 MATLAB 進行編碼方面還不夠成熟,否則請利用其原生的向量計算能力,因為它速度很快! =)

暫無
暫無

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

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