【问题标题】:Matlab performance: comparison slower than arithmeticMatlab性能:比较比算术慢
【发布时间】:2012-08-27 06:37:09
【问题描述】:

不久前,我向this question 提供了答案。

目标:统计该矩阵中[3 6]范围内的值的数量:

A = [2 3 4 5 6 7;
     7 6 5 4 3 2]

我想出了 12 种不同的方法:

count = numel(A( A(:)>3 & A(:)<6 ))      %# (1)
count = length(A( A(:)>3 & A(:)<6 ))     %# (2)
count = nnz( A(:)>3 & A(:)<6 )           %# (3)
count = sum( A(:)>3 & A(:)<6 )           %# (4)

Ac = A(:);
count = numel(A( Ac>3 & Ac<6 ))          %# (5,6,7,8)
%# prevents double expansion
%# similar for length(), nnz(), sum(),
%# in the same order as (1)-(4)

count = numel(A( abs(A-(6+3)/2)<3/2 ))   %# (9,10,11,12)
%# prevents double comparison and & 
%# similar for length(), nnz(), sum()
%# in the same order as (1)-(4)

所以,我决定找出哪个最快。测试代码:

A = randi(10, 50);
tic
for ii = 1:1e5

    %# method is inserted here

end
toc

结果(最好的 5 次运行,全部以秒为单位):

%# ( 1): 2.981446
%# ( 2): 3.006602
%# ( 3): 3.077083
%# ( 4): 2.619057
%# ( 5): 3.011029
%# ( 6): 2.868021
%# ( 7): 3.149641
%# ( 8): 2.457988
%# ( 9): 1.675575
%# (10): 1.675384
%# (11): 2.442607
%# (12): 1.222510

所以看来count = sum(( abs(A(:)-(6+3)/2) &lt; (3/2) ));是去这里最快的方式...

我用两个除法,一个加法和一个abs交易一个&lt;,执行时间不到一半!有没有人解释为什么会这样?

JIT 编译器可能会用内存中的单个值替换除法/加法,但仍然存在 abs...Branch 错误预测?像这样简单的事情似乎很愚蠢......

【问题讨论】:

    标签: performance matlab operators octave jit


    【解决方案1】:

    A(:)&gt;3 &amp; A(:)&lt;6 表达式需要计算两个条件,而 abs(A(:)-(6+3)/2) &lt; 3/2) 只计算一个条件。

    对于非常紧凑的计算密集型循环,这会产生很大的不同。即使没有分支错误预测,分支本身的成本也相对较高。这就是为什么,例如,loop unrolling 作为一种优化技术。

    【讨论】:

    • 三个 if 语句?这种事情不会被 JITed 到相当于if (element[i] &lt; 6) &amp;&amp; (element[i] &gt; 3){...} 吗?即使不是这种情况,也最多两个 if-statements,不是吗? if (element[i]&lt;6) return true; return false; ...&amp;&amp;...if (element[i]&gt;6) return true; return false;
    • 顺便说一下,&amp;&amp; 是短路的,但仅适用于标量。我使用了&amp;,因为这是使用数组的方法。奇怪,但事情就是这样。我希望在内部它们是相同的,但语法却不同。我要编辑你的帖子吗?
    • 我真的不知道分支的成本如此之高...我会记住这一点的。谢谢。
    • 当然,随时更改。我不流利地使用 matlab 并错过了 ;-)
    猜你喜欢
    • 2021-04-02
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    • 2016-04-25
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    相关资源
    最近更新 更多