APP下载

JAVA并行计算在CBTC维护系统中的应用研究

2013-05-08北京全路通信信号研究设计院有限公司北京100073

铁路通信信号工程技术 2013年1期
关键词:执行器线程子系统

王 俊(北京全路通信信号研究设计院有限公司,北京 100073)

王俊,男,硕士,毕业清华大学,助理工程师,主要从事区控系统开发,在CBTC系统项目中担任维护子系统负责人。

随着计算机技术的发展,多核处理器以及广泛应用于服务器、台式机和便携式计算机[1],用于维护系统服务器的处理器已多是四核以上。而用于服务器的操作系统如windows server 2003/2008均能支持多核,能够将多个线程在多个内核上并行的执行。这样,只要维护系统应用软件在设计时充分考虑多核系统的特性,将复杂的处理任务划分为若干可并行执行的任务,就能充分利用多核来提高应用软件的执行效率。

一般而言,并发(并行)编程比较复杂,需要处理线程同步、数据共享等一系列问题。而JAVA作为一种持续发展的、先进的编程语言,它一直在尝试提供更好的手段来降低并发(并行)编程的难度。另一方面,JAVA语言功能完善,易于代码编写和维护。它提供的Swing框架适合开发桌面维护系统,而J2EE对网络开发的支持,十分适合开发Browser-Server架构的维护系统。本文将在介绍JAVA语言并行计算技术发展的基础上,探讨JAVA并行计算技术在信号系统的维护子系统开发中的应用。

1 JAVA并行编程技术的发展

首先说明下一并行编程与并发编程的区别。并行编程关注的是充分利用计算资源更快的获取结果,而并发编程关注的是正确高效地控制多个线程访问共享的资源[2]。

传统的并发编程基于java.lang.Thread类和java.lang.Runnable接口实现。由程序员自己处理线程同步和数据共享的问题。这样的并发编程对于多个线程协同完成一个工作的情况下很容易产生错误,并且调试相当复杂,因为各个线程的调用时机会对执行结果产生影响。

正式因为传统并发编程的问题,JAVA SE6为我们提供了一系列的并发编程基元、集合和特性[1]。尤其是它提供了执行器,可以执行线程任务类似的任务,提供了线程池和调度策略,而且可以同步或者异步地获取执行的结果。

执行器是JAVA并发编程的一大进步,然而它的并行处理还存在问题。当一个并发任务需要等待另一并发任务的结果时,这个并发任务将被置于闲置状态,因此浪费了执行另一个等待的并发任务的机会。而JAVA SE 7中引入了分解/合并(Fork/Join)框架来帮助并行处理。

分解/合并框架的核心功能是新的Fork-JoinPool执行器,它用来执行ForkJoinTask任务。而ForkJoinTask可以分派子任务,并等待子任务完成。这样,ForkJoinPool执行器可以在任务等待另一个子任务完成时,利用计算资源处理其他待处理的任务。分解/合并框架提供了一种表示可并行化算法的简单方式[3],极大地简化了编写并发程序的琐碎工作[4]。

文献[1]在Oracle的Sun Fire T2000服务器上,通过指定Java虚拟机可用的内核数,测试了分解/合并方式和单线程形式以找出“import”在JDK源代码文件中出现的次数消耗的时间。结果表明分解/合并方式相对与单线程处理的性能提高随内核数目增加线性增长。

因此,在信号系统维护子系统开发中利用好JAVA的并行计算技术,能够大大提高“计算密集型”任务的执行效率,从而使得维护系统的响应时间更快,使得用户得到更好的体验。在CBTC系统中,随着各个子系统交互的信息增加,可以监测的信息也随之增加,提高维护系统的信息处理效率,能够让维护系统尽可能多的监测CBTC系统运行信息,给运行状态监测、故障预警分析提供更加充分的信息。

2 维护系统密集型任务分析

信号系统维护子系统的定位是对信号系统设备进行就地监测和远程报警,并辅助进行故障预警、分析,指导维修作业。维护子系统一般应具备的功能有:监测数据存储、信号设备状态监测、故障报警、查询回放、统计报表等。

为监测尽可能多的信息,维护子系统持续的接收大流量监测数据,处理这些数据的有以下几个瓶颈。1)数据的解析:由于监测信息的增加,数据解析的工作量也增加了。高效的解析数据能够实时流畅的显示信号系统设备的运行状态,并及时的给出故障报警。

2)数据的筛选:如果采用数据库,专业的商用数据库能高效地帮我们实现基本的数据查询,但是有时我们需要对查询的数据进一步筛选,如果筛选效率过低就会影响用户体验;如果采用文件系统,那么从数千万条记录中筛选我们需要的记录所需的响应时间会极大地降低用户体验。

3)数据的压缩与解压:为了节省磁盘空间,可能会选择在存储数据时对数据进行压缩。在数据导入导出过程中,为了便于数据的拷贝,也可能选择在导出时对数据进行压缩,在导入时在进行解压的策略。存储数据时的压缩如果耗时太大可能影响完整记录数据的功能,而导入导出时数据压缩、解压耗时太大又会降低用户体验。

以上几个维护子系统的瓶颈,都可以认为是“计算密集型”任务,可以利用并行计算技术提高效率。下文针对其中的数据解析问题,研究并行计算的实现方法。

3 并行计算在数据解析任务中应用

数据解析任务是从一个或多个缓存数据中按照协议解析出数据包含信息的过程。虽然待监测数据协议可能各有不同,但是大多协议可以归纳为一个典型的通信协议的格式如图 1所示。

对于典型通信协议,我们对通信内容进行域划分,直到最小的域,即一个字段。将单个字段的解析作为最细的操作任务,它可能是进行字节合并、移位和与或等简单的操作。这样,我们就可以套用JAVA分解/合并(Fork/Join)框架。对整个解析任务进行分解,如果当前解析任务可以拆分为子解析任务,则对解析任务进行分解;如果解析任务已经是最细解析任务,则进行数据解析,其伪代码如下。

依照伪代码的方式,解析任务按照如图2所示方式被分解。

经过这样的分解过程,解析任务不断地被分解为最细的解析任务,并放入ForkJoinPool执行器的线程池中,由JAVA的分解/合并框架来根据可用线程数来调度这些最细解析任务的操作,达到充分利用多核处理器提高解析信息效率的目的。

对于解析任务,也可以采用传统的并发编程的方式,对每一个最细的解析任务创建一个线程来实现。但是如果同时的线程数大于处理器支持线程数则会使处理器处理碎片化,不仅不会提高效率还可能降低处理;而如果同时的线程数小于处理器支持的线程数则又不能充分利用计算资源。并发编程中考虑线程数与内核数的匹配会增加编程的复杂度。而且随着硬件升级,内核数可能增加,这样并发编程就需要重新设计来适应。

而采用分解/合并框架,ForkJoinPool可以指定并行度,由分解/合并框架实现并行度与可用的硬件处理单元数目匹配,开发者只需要按照分解/合并的思路去分解“计算密集型”任务就能简单的实现并行计算,从而可以把更多精力投入业务设计中。

4 总结

本文介绍JAVA并行编程的发展,分析了在CBTC维护系统中应用JAVA并行编程的方法。JAVA并行编程在多核平台上能够提高维护系统“计算密集型”任务的效率,使维护系统能够实现更全面的维护监测并提供友好的时间响应性能。

[1] Julien Ponge.Fork and Join:Java Can Excel at Painless Parallel Programming Too![EB/OL].[2013-01-02].http://www.oracle.com/technetwork/articles/java/fork-join-422606.html.

[2] Dan Grossman.A Sophomoric Introduction to Shared-Memory Parallelism and Concurrency[EB/OL].[2013-01-02].http://wenku.baidu.com/view/e5438300eff9aef8941e067f.html###.

[3] Brian Goetz.Java理论与实践:应用fork-join 框架——学习如何使用Java 7中的fork-join框架实现细粒度并行性[EB/OL].[2013-01-01].http://www.ibm.com/developerworks/cn/java/j-jtp11137.html.

[4] 甘志,戴晓君.JDK 7中的Fork/Join模式——轻松实现多核时代的并行计算[EB/OL].[2013-01-02].http://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/index.html.

猜你喜欢

执行器线程子系统
不对中转子系统耦合动力学特性研究
基于C#线程实验探究
GSM-R基站子系统同步方案研究
基于国产化环境的线程池模型研究与实现
线程池调度对服务器性能影响的研究*
高锁螺母自动化安装机器人末端执行器设计
驼峰测长设备在线监测子系统的设计与应用
飞机装配预连接紧固件自动化安装末端执行器设计
考虑执行器饱和的改进无模型自适应控制
一类具有执行器饱和的非线性系统抗饱和方法研究