【问题标题】:Time comparison of "for" loop in Matlab and OctaveMatlab和Octave中“for”循环的时间比较
【发布时间】:2014-03-28 03:44:34
【问题描述】:

刚刚,我才知道 Matlab & Octave 使用的是来自Wikipedia 的 column-major。

在 Fortran、OpenGL 和 OpenGL ES、MATLAB、 GNU Octave、R、Julia、Rasdaman 和 Scilab。

所以我只是在 Matlab 和 Octave 中检查“for loop”的速度。结果如下:

Matlab

>> x = rand(10000);
>> tic; for i=1:10000 for j=1:10000 k=x(i,j); end; end; toc; % row-major
Elapsed time is 2.320215 seconds.
>> tic; for i=1:10000 for j=1:10000 k=x(j,i); end; end; toc; % column-major
Elapsed time is 0.433013 seconds.

正如预期的那样,列优先顺序比行优先顺序更快。

八度

> x=rand(5000);
> tic; for i=1:5000 for j=1:5000 k=x(i,j); end; end; toc; % row-major
Elapsed time is 77 seconds.
> tic; for i=1:5000 for j=1:5000 k=x(j,i); end; end; toc; % column-major
Elapsed time is 78 seconds.

两种情况的结果相同。

问题: 为什么行优先和列优先循环在 Octave 中执行相似,尽管它使用列优先对齐?

【问题讨论】:

  • 这可能解释了一些问题,尤其是 Octave 缺少 JIT:stackoverflow.com/questions/12569351/…
  • 我已经看过那个链接了。它解释了为什么 Matlab 循环比 octave 快得多(10000x10000 为 0.5 秒,而 Octave 中 5000x5000 为 78 秒),但我认为没有提及我的问题。
  • 使用feature accel off 再次运行您的测试我发现行优先版本或列优先版本之间没有真正的区别(与您的 Octave 结果非常相似)。所以 JIT 编译是时间上的差异,我猜非向量化循环不像 JIT 编译器使用的向量化版本那样依赖于矩阵的访问方式。
  • 哦,那太酷了。但同样,为什么 Matlab 和 Octave 没有区别?我的意思是,无论如何,按列循环应该更快,对吧?

标签: performance matlab octave memory-alignment


【解决方案1】:

为了扩展我的 cmets,我将发布一个答案。不过我不是这方面的专家。

首先,在 Matlab 中使用 feature accel off 运行测试以禁用 JIT 编译返回的结果与 Octave 的大致相同。因此,Matlab 和 Octave 之间的速度增加是由于 Matlab 的 JIT 编译,它必须对循环进行矢量化。

其次,Matlab 的 JIT 编译版本对于列优先而不是行优先的原因是因为 Matlab 是列优先的,这是有道理的。

那么对于没有 JIT 编译的 Octave 和 Matlab,列优先评估只是稍微快一点。由于每个值都是从随机矩阵中单独提取的,我可以理解为什么这会很慢,但不知道为什么行或列之间应该有很大差异。

希望无论如何都能有所帮助,也许其他人可以扩展/改进这个或发布一个真正的答案!

【讨论】:

  • +1 为答案。但是我还是不明白为什么没有 JIT 就没有区别。
  • 我认为这只是因为每次循环迭代,Matlab/Octave 必须去检索矩阵的单个元素,用它进行计算,然后检索下一个元素。它不是将矩阵的列加载到缓存中并使用每个元素,而是加载缓存的单个元素,然后删除(?)它们,然后将下一个元素加载到缓存中。
【解决方案2】:

如果您尝试对整个列或行进行操作,您会发现不同。在 MATLAB 和 Octave 中尝试以下代码:

%% Columns
a = rand(n);
b = zeros(n,1);
tic
for ii = 1:n
  b = b + a(:,ii);
end
t1 = toc

%% Rows:
a = rand(n);
b = zeros(1,n);
tic
for ii = 1:n
  b = b + a(ii,:);
end
t2 = toc

在我的电脑上,这给出了:

%% MATLAB:
t1 =  0.0287
t2 =  0.3778

%% Octave*:
t1 =  0.089480
t2 =  0.20313

现在,Octave 中的差异没有 MATLAB 中那么大,但 Octave 中的差异仍然很大(快两倍以上)。

David 已经发布了一个关于 JIT 编译的答案,所以我将在此处跳过该部分。

*我没有可用的 Octave,所以我必须测试它here

【讨论】:

    猜你喜欢
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多