如何在多台电脑上并行运行我的C#程序?最简单的方法是什么?

6

我家里有许多未使用的电脑。如果我想用最少或不需要改动代码的方式,利用它们将我的 C# 程序并行化,那么最简单的方法是什么?

我要完成的任务包括循环处理大量英语句子,数据集可以轻松地分成较小的块,在不同的机器上并发处理。


你可以透露一下你想要实现什么吗?你是否考虑过使用数据库和/或全文索引来满足你的需求? - vmarquez
需要更多细节。仅凭您的问题,我们是否可以假设并行化是为了提高单次运行的速度?也可以考虑您只是想在多台机器上执行相同的操作-这有完全不同的答案。 - Klathzazt
9个回答

7
“…没有或很少代码更改?”
很困难。基本上,可以考虑使用WCF来在网络中的各个程序实例之间进行通信。根据算法,结构可能需要彻底改变,也可能完全不需要。无论如何,您都必须找到一种方法将问题分成相互独立的部分。然后,您必须设计一种方法来将这些部分分布在不同的实例之间,并收集结果数据。 PLinq提供了一种很好的方法来并行化程序,而不需要进行大的更改,但这仅适用于一个进程,在不同线程之间,仅当算法适合并行化时才有效。一般来说,一些手动重构是必要的。

2

Dryad(微软的MapReduce变种)正好解决了这个问题(将.NET程序并行化在多台PC上)。它目前处于研究阶段。很遗憾还没有CTP版 :-(


discontinued - kmote

2

这可能是不可能的。

如何并行化程序完全取决于您的程序做什么以及它是如何编写的,通常需要进行大量代码更改,并且使您的程序复杂度增加多倍。

通常简单地增加程序的并发性的方法是将重复执行的任务拆分成多个块,并编写一个函数将这些块发送到不同的核心进行处理。


2
答案取决于您的应用程序将要处理的工作的性质。不同类型的工作有不同可能的并行化解决方案。对于某些类型,没有可能或可行的并行化方式。
我能想到的最简单的情况是针对可以轻松将工作分成离散的作业块的应用程序。如果是这种情况,则只需设计您的应用程序以处理单个作业块即可。为应用程序提供接受新作业和交付完成作业的功能。然后,在其上构建作业调度程序。此调度程序可以是同一应用程序的一部分(配置一个机器作为调度程序,其余机器作为客户端),也可以是一个独立的应用程序。
还有其他事项需要考虑:机器之间的通信如何进行(文件?网络连接?);应用程序需要能够报告/查询已完成的作业百分比吗?;是否需要能够强制应用程序停止处理当前作业?等等。
如果您需要更详细的答案,请编辑您的问题并包括有关应用程序、应用程序解决的问题、预期作业数量等的详细信息。然后,社区将提出更具体的答案。

1

你需要在分布式系统上运行应用程序,可以通过谷歌搜索“分布式计算窗口”或者“网格计算C#”来获取相关信息。


1
每个句子是独立处理的,还是它们以某种方式组合起来处理?如果您的处理一次只能处理一个句子,那么您无需改变您的代码。只需在每台机器上执行相同的代码,并将数据(您的句子列表)分配给它们。您可以通过在每台机器上安装部分数据,或共享数据库并将不同的块分配给每台机器来实现这一点。
如果您想稍微更改代码以便于并行处理,请共享整个数据库,并让代码“标记”每个已处理的句子,然后查找下一个未标记的句子进行处理。这将为您介绍线程安全的概念 - 这是确保一个处理器不会对另一个处理器产生负面干扰的技术之一。
像往常一样,您提供的有关特定应用程序的详细信息越多,SO社区就能更好地根据您的目的量身定制我们的答案。
祝你好运 - 这听起来像是一个有趣的项目!

0

0
在投资并行化您的程序之前,为什么不尝试将数据集分成几部分,手动在每台计算机上运行程序,并手动整理输出结果呢?如果这样可以解决问题,那么再尝试使用脚本自动化,并编写一个程序来整理输出结果。

0
您可能想看看 基于流程的编程 - 它有Java和C#的实现。大多数解决此问题的方法涉及尝试将传统的单线程程序分解成可并行运行的部分。FBP采用了不同的方法:应用程序从一开始就按照多个异步运行的“黑盒”组件设计(类似制造业的装配线)。由于传统的单线程程序在FBP环境中就像一个组件,因此很容易扩展现有应用程序。实际上,现有应用程序的某些部分通常可以拆分为单独的组件,只要它们可以与应用程序的其余部分异步运行(即不是子例程)。有人称之为“将冰山变成冰块”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接