2013-08-16 97 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