2013-07-23 91 views
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出現奇怪的測量。

所以我的問題是:有沒有其他人在一定範圍內遇到這種情況,是什麼原因造成的? (這是一個錯誤?)

+0

那麼我肯定會承擔'ABS(X)> 0'就慢,因爲它是真正做2次運算,但10萬的N個審判,不遵循這一點。奇怪。但是我幾乎總是使用'x〜= 0',因爲它只執行一個操作。還要注意,兩者之間的差別對我而言並不像對你那麼高。第三次審判只是0.4秒而不是1.5 – MZimmerman6

+0

我唯一的想法就是在背景中有一些奇怪的內存分配在100k試用版拋出 – MZimmerman6

+0

我看到相同的東西,但沒有那麼激烈(R2012b,OS X 10.8.4)。我不會「假設」abs(x)> 0'執行兩個操作。一旦編譯了JIT,比較中的符號位可以被忽略。它實際上是'x〜= 0'情況更復雜(相當於'x> 0 | x <0')。大小之間差異的一個可能的原因可能是[cache missing](https://en.wikipedia.org/wiki/CPU_cache#Cache_miss),詳細討論[here](http://stackoverflow.com/questions/8547778 /爲什麼,是一環那麼多,慢於雙循環)。 – horchler

回答

6

這可能是由於一些自動優化MATLAB用於其基本線性代數子程序。

與您的一樣,我的配置(OSX 10.8.4,R2012a和默認設置)需要更長的時間來計算x(10e5元素)的idx1 = x~=0比x(11e5元素)要多。請參見圖中左側面板,其中處理時間(y軸)針對不同的矢量大小(x軸)進行測量。對於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做最好的工作可能適合你。「enter image description here

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 
+0

我想理想的情況是優化會盡快結束。所以,如果我理解正確:對於此操作(在我們的計算機上),優化只是爲時已晚? –

+0

是的 - 你已經找到了「爲你最好的工作」設置/限制之一。但是,無疑matlab的開發人員會意識到這一點,並故意這樣做。 – marsei

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. 
+0

有趣的是,看到切換JIT實際上使得它更快。但是,如果熱身會成爲問題,這並不能解釋爲什麼100000比150000慢。注意,如果您更改順序'N = [10000 15000 150000 100000]' –

+0

也會發生這種情況,我認爲這種熱身不起作用在命令行上。我基本上猜測,使用JIT有一些開銷,這可能是可變大小的函數,還有一些好處也是可變大小的函數。最終效益大於開銷,但直到x> 150000左右(在這種情況下)的大小。 – nkjt

+0

它可能不是來自JIT實際 - 請參閱我的答案。 – marsei