使用.net Remtoing进行并行计算

使用 .net Remtoing 并行计算

摘要,本文分析了一个使用 .net romoting 进行并行计算 PI 值的程序,

并给出结果及性能分析。

在 MSDN 上发现一篇文章是介绍如何使用 .net Remoting 进行并行计算的,刚好本人对并行计算很有兴趣,于是仔细地分析了一下此程序的代码。 _ 原文 _ 及 _ 程序 _ 可以在 _ 此处 _ 获得。由于觉得原文只是作了一个大致的讲解,有很多细节只是掩藏在源代码中,所以在花了很多时间分析完源程序后,才对原文有了很深的理解,疏理出一些内容出来和大家分享。

** 一. ** ** 概述 ** ** **

.NET Remtoing 用于在远程服务器和客户机之间互相调用对象,这些对象是存在于同一 AppDomain 中的。它使用 Soap 或二进制的方式传递消息(即要调用的对象),传送协议为 HTTP 或 TCP 。

** 二. ** ** Remoting ** ** 如何实现并行计算? ** ** **

.NET Remoting 与并行计算好像是两个不同的概念,前者更类似于分布式计算和 Web Service ,而后者实际上是计算粒度更小的任务,但它将一个计算任务分配给多个节点计算,然后汇总成一个结果返回。

根据以上思想,实现上将分布的对象的粒度设计小一点即可实现并行计算。并行计算的一个关键因素是进程(或子任务)间通讯,而我们把 .net remoting 中的对象间通讯作为进程间通讯即可。

本例并行计算 Pi 的小数点,精确到 N 位。使用 .net remoting 可以如下实现。在每个节点上运行相同的程序,但每个节点计算不同位置的小数位,如 NodeA 计算小数点后 1-9 位, NodeB 计算 10-18 位, NodeC 计算 19-27 位,这样最终汇总的结果就可以有 1-27 位。由于是并行计算,比起单机计算,时间要快上很多倍,其加速比与每台节点的速度及整个通信网络的速度有关。计算模型如下图所示:

** **

** 三. ** ** 并行算法 ** ** **

要进行并行计算,首先要设计好并行算法和通讯模式。由于我们只是在 PC 机群进行并行计算,所以采用了最简单的主从式并行模型,即由一个主进程负责任务的分发,结果的归约,将子任务平均分配到每个节点上计算。

但实际上本文中使用的并不是平均分配任务,而是更好的任务池工作方式。即每个节点计算完一个子任务后,会向主进程申请新的任务,一直到任务全部计算完为止,这样的好处是计算能力越强的节点计算的任务也越多。比起平均分配来说可以提高总体的计算和减少同步时间。


** 四. ** ** 程序结构 ** ** **

此程序主要由以下几个包组成,

l ** 4 ** ** . 1 ** ** ) ServerLoader **

用于加载提供可远程调用的服务器对象,指定调用使用的网络协议和端口,以便于在局域网中被调用,然后侦听来自客户端的请求, 在服务器上 处理此请求并返回结果。

简单来说即每个节点都必须运行 ServerLoader 程序,以向外界声明可被调用的对象(即 Plouffe_bellard.dll 中的对象)。

以下代码为调用配置文件:

String ConfigFilePath = Path.GetDirectoryName(Application.ExecutablePath) + ServerLoader. exe.config";

RemotingConfiguration.Configure(ConfigFilePath);

配置文件为: **_ ServerLoader.exe.config _ **

 1<configuration>
 2<system.runtime.remoting>
 3<application name="ServerLoader">
 4<service>
 5<wellknown mode="SingleCall" objecturi="Plouffe_Bellard" type="PB.Plouffe_Bellard,Plouffe_Bellard"></wellknown>
 6</service>
 7<channels>
 8<channel port="9000" ref="tcp server"></channel>
 9</channels>
10</application>
11</system.runtime.remoting>
12</configuration>

l ** 4 ** ** . 2 ** ** ) Plouffe_bellard **

这就是 .NET Remoting 中的实际被调用的远程对象,它被置于每个节点上。它是继承自 System.MarshalByRefObject , 这样的派生对象从来都不会离开它的应用域,客户就可以通过代理对象调用远程对象的方法。

它是用来计算圆周率 PI 的小数点位数的程序, Plouffe_Bellard 算法具有很好的并行性,它可以指定要计算的小数点的位置,如第二节所述。

其函数形式为:

public class Plouffe_Bellard : System.MarshalByRefObject

{

public String CalculatePiDigits( int n)

{ … }

}

l ** 4 ** ** . 3 ** ** ) DigitsOfPi **

此子基础上为整个项目核心部分,可作为客户端程序运行。它主要实现主界面 UI 处理、节点配置,多线程创建与同步,计算任务分配与汇总的功能,只需要在任何一台节点上运行即可。包括以下几个对象:

MainForm , SolutionArray , SolutionItem , RemotingObject , CalculationThread 。

n mainForm :即处理 UI 对象

n SolutionArray 是并行线程分配与管理程序,如 : 任务池创建、任务分配、线程创建、同步线程 , 汇聚结果等。

n SolutionItem 即任务的数据结构。包括要计算的小数点位 , 计算的结果 , 计算的在机器。

n RemotingObject 是 RemotePiCalculator,用于获取远程对象。

n CalculationThread:计算模块,在线程中运算(由SolutionArray产生和调用),并不断从任务池中取得任务进行计算。

以下为这几个对象的序列图:


当远程对象的 CalculatePiDigits 被客户端程序调用时,此要求即被发送到远程机器的 ServerLoader 对象。然后服务器上的对象就会计算结果。最后将计算的结果返回给客户端程序,显示在文本框中。

** 五. ** ** 结果分析 ** ** **

机器配置说明

MOORE 700MHz AMD Duron 192M SDR

LOZIT 1.8GHz Batumn 256M DDR

时间比较

由于算法的特性,计算到高位时可以看到计算速度逐渐变慢。在我们的机器上,算到第 3000 位附近速度已经是非常之慢,忍受不住终于中断,一共计算了 3330 位,共耗时 719545 ms ,即 12 分钟。在实验中还发现,节点只能与同一子网中其它节点相连才有效,要与子网外的节点相连,可能要涉及 .net 中的更高级话题,就不太清楚了。

** 六. ** ** 后记: ** ** **

本文中的并行算法相对简单,没有涉及并行计算的高级算法及其它内容,如子任务间并没有传递数据。使用 .net remoting 是否适合作并行计算呢?当在科学计算领域中已经有现成的 MPI , MVP 等并行通讯库可用时?如果可以出现 MPI for C# ,那真是一大福音。(好像俄罗斯的专家们已经实现了这个项目,叫做 T-System[2] )。如果有时间,希望会在以后我文章中继承研究用 .net remoting 进行并行计算。国外的一些研究组好像已经有不少开始这方面的研究,希望有兴趣的朋友和本人联系,一同探讨。

2004 年 4 月 20 日星期二

_ [email protected] _

参考文献:

1. Parallel Computing with .NET Remoting , Eric Bergman-Terrell

_ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnhcvs03/html/vs03d1.asp _

2. Alexander Chudinov , Vladimir Roganov , Parallel Computing Runtime for Microsoft .NET Framework

_ wscg.zcu.cz/Rotor/NET_2003/Papers/Chudinov.pdf _

Published At
Categories with Web编程
Tagged with
comments powered by Disqus