簡體   English   中英

Matlab:過濾大型數組元素,更快地替代邏輯索引嗎?

[英]Matlab: filtering large array elements, quicker alternative to logical indexing?

我有一個大型的三維浮點數據集,大約有5億個元素(3000 x 300 x 600)。

我想將低於或高於某些閾值的元素設為零。 邏輯索引可以做到這一點,例如

cut_in = 0.5
cut_out = 6
Hs(Hs<cut_in) = 0 ;
Hs(Hs>cut_out) = 0 ;

問題在於,對於大數據量來說,這對於我來說是緩慢的。 上面的代碼需要240秒才能在我的計算機上運行。 有沒有更快的方法可以做到這一點?

非常感謝

正如@rayryeng和@AndrasDeak在對問題的注釋中指出的那樣,邏輯索引通常是最快的,盡管您的運行時建議您可能受內存(並被強制交換到磁盤)的限制,而不是受索引實際速度的限制。

在這種情況下可以勝出的一種令人驚訝的替代方法是for循環。 這是因為邏輯索引需要遍歷該數組三遍(每個不等式測試一次,一次更改數據),而for循環僅需要遍歷該數組一次。

基准

因此,我在內存為8 GB的計算機上運行了這些測試(並意外地使數組大小增加了一倍):

>> A = randn(6000,300,600);
>> cut_in = -1;
>> cut_out = 1;

使用for循環:

>> tic; for i=1:numel(A), if A(i)<cut_in || A(i)>cut_out, A(i)=0; end; end; toc
Elapsed time is 597.384884 seconds.

使用邏輯索引:

>> tic; A(A<cut_in | A>cut_out) = 0; toc
Elapsed time is 1619.105332 seconds.

只是為了笑(我花了一些時間等待基准測試運行),這是一個編譯的for循環:

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *A = mxGetPr(prhs[0]);
    size_t N = mxGetNumberOfElements(prhs[0]);
    double cut_in = *mxGetPr(prhs[1]);
    double cut_out = *mxGetPr(prhs[2]);
    // You're not supposed to do in-place operations! Don't do this!
    for (ptrdiff_t ii=0; ii<N; ii++) {
        if ((A[ii]<cut_in) || (A[ii]>cut_out))
            A[ii] = 0;
    }
}

並進行基准測試:

>> mex -v CXXOPTIMFLAGS="-O3 -DNDEBUG" -largeArrayDims apply_threshold.cpp
>> tic; apply_threshold(A,cut_in,cut_out); toc
Elapsed time is 529.994643 seconds

要記住的一件事是,我們在一種操作環境中進行操作,其中訪問交換空間是性能的主要瓶頸,因此,即使在同一台機器上,基准測試結果也可能有所不同,具體取決於主內存中的當前內容(與之相對)。需要交換)以及正在運行哪種后台進程。

暫無
暫無

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

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