我一般只用idl进行后处理,而不用他做计算,所以很少关心他的运行效率。最近的一些数据实在太大,处理过程中又需要做一定量计算,发现idl计算很多时候都是一个进程在工作,这对于多核cpu来说太浪费了,而且我的程序中很多都是异步计算,要实现并行应该是很简单的。于是我google了一下,发现有FastDL,TaskDL,mpiDL一类的第三方软件,但这些东西用起来比较麻烦,而且似乎没有windows版,对于我这种只需要简单的并行来说没有必要。于是我发现了idl内置的IDL_IDLBridge功能,它能创建另外的idl进程,这个功能完全能满足简单并行计算的需求。下面从一个简单的实例来看看它需要注意的地方。

比如,有2个数据,分别为data_a和data_b,先把data_a和data_b做10000次乘法,得到data_c;再把data_a和data_b做10000次除法得到data_d,把data_c和data_d相加后得到最终结果。这么一个简单的流程如果一路做下来,是浪费时间的。比如得到data_c和得到data_d的过程是独立的,idl在计算data_c的时候其实就可以同时计算data_d。但你打开任务管理器就会发现idl没有这么干,于是我们得使用IDL_IDLBridge功能来实现并行。

看了IDL_IDLBridge的帮助后你可能会这样写程序:

oBridge = OBJ_NEW('IDL_IDLBridge')
oBridge->Execute,'multiply,data_a,data_b,data_c'
oBridge->Execute,'division,data_a,data_b,data_d'
result=data_c+data_d

恭喜你,流程对了,但你的程序还是没有并行起来,因为IDL_IDLBridge::Execute默认是“Synchronous”。执行oBridge->Execute,’multiply,data_a,data_b,data_c’的时候主程序会halt,一直等到它执行完后才会执行完后才会执行oBridge->Execute,’division,data_a,data_b,data_d’。若要异步执行,则需要加入/nowait参数。但显然,事情没这么简单,你若只加入/nowait,他会提示你
IDL_IDLBRIDGE Error: The object's associated IDL process is currently busy.

要异步,上面的代码就要注意2个问题:(1)参数的传递,这可以用SetVar和GetVar来搞定;(2)并行状态控制,用IDL_IDLBridge::Status来查询。

好了,简单的代码可以这样写:

oBridge1 = OBJ_NEW('IDL_IDLBridge')
obridge1->setvar, 'data_a', findgen(10000)
;同样的data_b和data_c也要设置,这里省略
oBridge1->Execute,'multiply,data_a,data_b,data_c',/nowait
print,oBridge1->Status()
;可以看一下状态,运行的时候是1,证明返回主程序了
oBridge2 = OBJ_NEW('IDL_IDLBridge')
;新设置一个进程来并行计算
obridge2->setvar, 'data_a', findgen(10000)
;同样的data_b和data_d也要设置,这里省略
oBridge2->Execute,'division,data_a,data_b,data_d',/nowait
print,oBridge2->Status()
;看看实时状态,电脑不逆天的话也应该是1
while ((oBridge1->Status() EQ 1) or (oBridge2->Status() EQ 1)) do begin
endwhile
;后面要做加法,所以只要还在算,就必须要等
print,oBridge1->Status() & print,oBridge2->Status()
;确认一下状态为0,表示两进程都算完了
c1=oBridge1->GetVar('data_c') &c2=oBridge2->GetVar('data_d')
obj_destroy, obridge1 & obj_destroy, obridge2
;取回数据后释放掉
result=c1+c2

大体思路就是这样,代码显然可以优化。中间的SetVar和GetVar用起来很烦,可以用SHMMAP和SHMVAR来做,common也应该行吧?没试了。另外,idl自己宣称做一些计算会自动并行。好了,这就是简单的在win平台上用IDL_IDLBridge实现IDL并行计算,其他太复杂的计算,或者把idl安装到大机群的还是建议用fortran或者c。

标签: , , ,

5 条评论 发表在“在win平台上用IDL_IDLBridge实现IDL并行计算”上

  1. u说道:

    用SHMMAP效率比GetVar高很多
    这几天正好也在折腾win上IDL多线程的事情,还是太麻烦。。。

  2. […] 转载自:https://www.wingwy.com/archives/2013_08_1480.html document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000) var ujian_config = {num:10,itemTitle:'你可能感兴趣:'}; 本文作者:Sailor,一个不懂GIS的GISer,80末90初的第一代人,修行于中国海洋大学;喜欢折腾,向往自由,假文艺,真屌丝;欢迎联系,欢迎交流。QQ:61817708 Google+ […]

  3. 求助说道:

    用pecmd开机默认显示分辨率我懂 如:disp w1920 h1080 b32。。。如何开机默认“显示隐藏文件、文件夹和驱动器”和“隐藏已知文件类型的扩展名”

留下回复(本站有评论邮件通知功能)