10

在尝试选择推荐哪种索引方法时,我尝试测量性能。然而,测量结果让我很困惑。我以不同的顺序运行了多次,但测量结果保持一致。以下是我衡量性能的方法:

for N = [10000 15000 100000 150000]
    x =  round(rand(N,1)*5)-2;
    idx1 = x~=0;
    idx2 = abs(x)>0;

    tic
    for t = 1:5000
        idx1 = x~=0;
    end
    toc

    tic
    for t = 1:5000
        idx2 = abs(x)>0;
    end
    toc
end

这是结果:

Elapsed time is 0.203504 seconds.
Elapsed time is 0.230439 seconds.

Elapsed time is 0.319840 seconds.
Elapsed time is 0.352562 seconds.

Elapsed time is 2.118108 seconds. % This is the strange part
Elapsed time is 0.434818 seconds.

Elapsed time is 0.508882 seconds.
Elapsed time is 0.550144 seconds.

我检查了大约 100000 的值,这也会发生,即使在 50000 时也会发生奇怪的测量。

所以我的问题是:有没有其他人在一定范围内经历过这种情况,是什么原因造成的?(这是一个错误吗?)

4

2 回答 2

7

我认为这与 JIT 有关(以下结果使用 2011b)。根据系统、Matlab 的版本、变量的大小以及循环中的确切内容,使用 JIT 并不总是更快。这与“热身”效应有关,有时如果您在会话中多次运行 m 文件,第一次运行后它会变得更快,因为加速器只需编译部分代码一次。

JIT 开启(功能加速开启)

Elapsed time is 0.176765 seconds.
Elapsed time is 0.185301 seconds.

Elapsed time is 0.252631 seconds.
Elapsed time is 0.284415 seconds.

Elapsed time is 1.782446 seconds.
Elapsed time is 0.693508 seconds.

Elapsed time is 0.855005 seconds.
Elapsed time is 1.004955 seconds.

JIT 关闭(功能加速关闭)

Elapsed time is 0.143924 seconds.
Elapsed time is 0.184360 seconds.

Elapsed time is 0.206405 seconds.
Elapsed time is 0.306424 seconds.

Elapsed time is 1.416654 seconds.
Elapsed time is 2.718846 seconds.

Elapsed time is 2.110420 seconds.
Elapsed time is 4.027782 seconds.

ETA,看看如果你使用整数而不是双精度会发生什么有点有趣:

JIT on,相同的代码,但使用 int8 转换了 x

Elapsed time is 0.202201 seconds.
Elapsed time is 0.192103 seconds.

Elapsed time is 0.294974 seconds.
Elapsed time is 0.296191 seconds.

Elapsed time is 2.001245 seconds.
Elapsed time is 2.038713 seconds.

Elapsed time is 0.870500 seconds.
Elapsed time is 0.898301 seconds.

JIT 关闭,使用 int8

Elapsed time is 0.198611 seconds.
Elapsed time is 0.187589 seconds.

Elapsed time is 0.282775 seconds.
Elapsed time is 0.282938 seconds.

Elapsed time is 1.837561 seconds.
Elapsed time is 1.846766 seconds.

Elapsed time is 2.746034 seconds.
Elapsed time is 2.760067 seconds.
于 2013-07-23T13:27:50.967 回答
6

这可能是由于 matlab 对其基本线性代数子程序使用了一些自动优化。

就像你的一样,我的配置(OSX 10.8.4,R2012a 具有默认设置)需要更长的时间来计算idx1 = x~=0x(10e5 元素)而不是 x(11e5 元素)。请参见图的左侧面板,其中测量了不同矢量大小(x 轴)的处理时间(y 轴)。您将看到 N>103000 的处理时间较短。在此面板中,我还显示了计算期间活动的核心数。您将看到单核配置没有下降。这意味着当 1 个内核处于活动状态时,matlab 不会优化执行~=(不可能进行并行化)。当满足两个条件时,Matlab 会启用一些优化例程:多核和足够大小的向量。

feature('accel','on'/off')设置为关闭 ( doc ) 时,右侧面板会显示结果。在这里,只有一个内核处于活动状态(1 核和 4 核相同),因此无法进行优化。

最后,我用于激活/停用核心的功能是maxNumCompThreads. 根据Loren Shure的说法,maxNumCompThreads 控制 JIT 和BLAS。由于feature('JIT','on'/'off')没有在表演中发挥作用,BLAS 是剩下的最后一个选项。

我将把最后一句话留给 Loren:“这里的主要信息是,您通常根本不需要使用此函数 [maxNumCompThreads]!为什么?因为我们想让 MATLAB 为您做最好的工作。”在此处输入图像描述

accel = {'on';'off'};
figure('Color','w');
N = 100000:1000:105000;

for ind_accel = 2:-1:1
    eval(['feature(''accel'',''' accel{ind_accel} ''')']);
    tElapsed = zeros(4,length(N));
    for ind_core = 1:4
        maxNumCompThreads(ind_core);
        n_core = maxNumCompThreads;
        for ii = 1:length(N)
            fprintf('core asked: %d(true:%d) - N:%d\n',ind_core,n_core, ii);
            x =  round(rand(N(ii),1)*5)-2;
            idx1 = x~=0;
            tStart = tic;
            for t = 1:5000
                idx1 = x~=0;
            end
            tElapsed(ind_core,ii) = toc(tStart);
        end
    end
    h2 = subplot(1,2,ind_accel);
    plot(N, tElapsed,'-o','MarkerSize',10);
    legend({('1':'4')'});
    xlabel('Vector size','FontSize',14);
    ylabel('Processing time','FontSize',14);
    set(gca,'FontSize',14,'YLim',[0.2 0.7]);
    title(['accel ' accel{ind_accel}]);
end
于 2013-07-28T01:33:12.223 回答