2013-08-16 76 views
0


我正在使用Google Earth工具箱,用於Octave,這與爲MATLAB編制的相同庫非常相似。有關該工具的MATLAB文檔,請參見this link優化八度/ matlab函數的運行時間

不幸的是我對某個功能有點麻煩:ge_quiver。該函數創建顫抖圖並將結果轉換爲KML代碼。我的問題 是,它有點太慢,我不喜歡。

對於30x30大小的數據變量,該函數大約需要10秒才能完成。這很好,除了我試圖製作一個動畫顫動情節以及其他23個相同大小的數據變量(共24個)。由於Octave(和MATLAB就此而言)通常只在一個線程上運行,因此整個事件將連續運行,並且需要10 * 24 = 240 s。

我試過parfor循環,但它們只從總運行時間中移除了10秒。我有一個16核的電腦。考慮,這是尷尬的並行(變量之間沒有相關性),這理想地應該採取:

10秒前16個變量
+ 10秒的剩餘8個變量
--------- ---------------------------------------------
= 20秒總。

我甚至沒有測試過arrayfun,因爲我不知道如何調整我的函數(p_ge_quiver)。儘管如此,許多人說arrayfun不會讓它變得更快。

下面的代碼大概是我想要做的。請記住變量 data_u的大小爲30x30x24。 data_vlonlat也是如此。

... 
... 

[YYYY,MM,DD,HH,mm,ss] = ncdate(NCFILE); 
date_s.year = YYYY; 
date_s.month = MM; 
date_s.day = DD; 
date_s.hour = HH; 
date_s.minute = mm; 
date_s.second = ss; 

TIMESTEP = 60; 
parfor i = 1:size(data_u,3) 
    dt  = TIMESTEP*i; 
    kml(i) = p_ge_quiver(lon,lat,data_u,data_v,dt,TIMESTEP,data_s); 
endparfor 

... 
... 

function kml = p_ge_quiver(lon,lat,u,v,data_time,step,date_s) 
% V_GE_QUIVER - Writes the quiver plot into KML. 

    % Get date variables. 
    YYYY = date_s.year; 
    MM = date_s.month; 
    DD = date_s.day; 
    HH = date_s.hour; 
    mm = date_s.minute; 
    ss = date_s.second; 

    % Date format. Use Google's. 
    F = 'yyyy-mm-ddTHH:MM:SSZ'; 

    % Start and end dates of data. 
    tStart = datestr(datenum(YYYY,MM,DD,HH,mm+data_time,ss),F); 
    tEnd = datestr(datenum(YYYY,MM,DD,HH,mm+data_time+step,ss),F); 

    % Quiver plot. 
    kml = ge_quiver(lon,lat,u,v,'timeSpanStart', tStart, ... 
           'timeSpanStop' , tEnd , ... 
           'visibility' , 0  , ... 
           'lineColor' , 'AAFFFFFF'); 



end 
+0

糾正我,如果我錯了,但我不認爲''parfor'是在Octave中實現的(它被解析器識別,但現在只是一個常規的'for'-loop)..它有一些函數用於'general'包中的並行計算:http://octave.sourceforge。net/general/overview.html#ParallelComputing – Amro

+0

我也讀過這個,但是我測量了for和parfor實現之間的10秒差異。很混亂。 – jhc

+0

我假設(至少在Matlab中)在運行你的代碼之前你打開了一個'matlabpool'?雖然三個30×30×24的數組並不是很多內存,但誰知道'ge_quiver'在內存中是怎麼做的。 – horchler

回答

0

在我看來,這個問題是什麼ge_quiver並在內部,你不顯示。除此之外,你應該注意到這種語言被設計爲編寫矢量化代碼(不僅因爲速度的差異)。

看你的代碼,你可以把它簡化很多(這通常不會有速度的效果也一樣)通過利用矢量語法:

step = 60; 
dt = step:step:(step * size (data_u, 3)); 

## Get date variables. 
YYYY = date_s.year; 
MM = date_s.month; 
DD = date_s.day; 
HH = date_s.hour; 
mm = date_s.minute; 
ss = date_s.second; 

## Date format. Use Google's. 
F = "yyyy-mm-ddTHH:MM:SSZ"; 

tStart = datestr (datenum (YYYY, MM, DD, HH, mm + dt  , ss), F); 
tEnd = datestr (datenum (YYYY, MM, DD, HH, mm + dt + step, ss), F); 

在這一點上,tStarttEnd有所有你需要的日期,每行一次。唯一需要的循環是:

for i=1:rows(tStart) 
    kml = ge_quiver (lon, lat, data_u, data_v, "timeSpanStart", tStart(i,:), ... 
               "timeSpanStop" , tEnd(i,:) , ... 
               "visibility" , 0   , ... 
               "lineColor" , "AAFFFFFF"); 
endfor 

在這一點上更是全部依賴什麼ge_quiver一樣。鏈接的mathworks網站顯示爲處於維護狀態。我看着the Google Earth toolbox website並找不到該功能(儘管它們有ge_quiver3函數)。

我認爲這種語言的函數應該允許向量輸入,所以請確認它。也許你根本不需要循環。

+0

我明白,代碼應該是矢量化的,但ge_quiver正是我想要矢量化的函數不在您的解決方案中。您的解決方案可能會從我的總運行時間中刪除幾個毫秒,但就是這樣。 – jhc

+0

@jhc好吧,除非您告訴您更改'ge_quiver'或告訴我們如何使用它,否則沒有優化可以做。你的鏈接再次運行,但我仍然沒有'ge_quiver'功能。 – carandraug

+0

是的,出於某種原因,新的工具箱沒有ge_quiver。無論如何,我想要做的是在不同的線程中運行每個ge_quiver,但我根本無法弄清楚。 parfor應該已經工作了。 – jhc