8

最近我读了很多关于 .NET 中的并行编程的文章,但我仍然对关于这个主题的文本的矛盾陈述感到困惑。

例如,stackoverflow.com task-parallel-library 标签的弹出窗口(将鼠标指向标签图标时)描述:

“任务并行库是 .NET 4 的一部分。它是一组 API,使开发人员能够对多核共享内存处理器进行编程”

这是否意味着使用早期版本的 .NET 无法实现多核和并行编程应用程序?

我是否控制 .NET 多线程应用程序中内核之间的多核/并行使用/分布?

如何识别要在其上运行线程并将线程归因于特定核心的核心?

.NET 4.0+ 任务并行库启用了哪些在以前的 .NET 版本中无法做到的事情?

更新:
嗯,很难提出具体的问题,但我想更好地理解:

.NET 中开发多线程应用程序和并行编程有什么区别?

到目前为止,我无法掌握它们之间的区别

Update2:
MSDN “.NET Framework 中的并行编程”从 .NET 4.0 版本开始,其文章Task Parallel Library告诉我们:

“从 .NET Framework 4 开始,TPL 是编写多线程和并行代码的首选方式”

考虑到我熟悉多线程开发,您能否给我提示如何在 pre-.NET4(在 .NET3.5 中)专门创建并行代码?

4

5 回答 5

14

我将“多线程”视为术语所说的:使用多个线程。

“并行处理”将是:在多个线程之间拆分一组工作,以便可以并行处理工作。

因此,并行处理是多线程的一种特殊情况。


这是否意味着使用早期版本的 .NET 无法实现多核和并行编程应用程序?

一点也不。你可以使用Thread类来做到这一点。写起来要困难得多,要正确地写起来困难得多。

我是否控制 .NET 多线程应用程序中内核之间的多核/并行使用/分布?

不是真的,但你不需要。您可以为您的应用程序处理处理器亲和性,但在 .NET 级别上,这几乎不是一个成功的策略。

任务并行库包含一个“分区器”概念,可用于控制工作的分配,这是控制线程在内核上的分配的更好解决方案。

如何识别要在其上运行线程并将线程归因于特定核心的核心?

你不应该这样做。.NET 线程不一定与 OS 线程相对应;你的抽象层次比这更高。现在,默认的 .NET 主机确实会一对一地映射线程,因此如果您想依赖未记录的实现细节,那么您可以深入了解抽象并使用 P/invoke 来确定/驱动您的处理器亲和力。但如上所述,它没有用。

.NET 4.0+ 任务并行库启用了哪些在以前的 .NET 版本中无法做到的事情?

没有。但它确实使并行处理(和多线程)变得更加容易!

考虑到我熟悉多线程开发,您能否给我提示如何在 pre-.NET4(在 .NET3.5 中)专门创建并行代码?

First off, there's no reason to develop for that platform. None. .NET 4.5 is already out, and the last version (.NET 4.0) supports all OSes that the next older version (.NET 3.5) did.

But if you really want to, you can do simple parallel processing by spinning up Thread objects or BackgroundWorkers, or by queueing work directly to the thread pool. All of these approaches require more code (particularly around error handling) than the Task type in the TPL.

于 2013-03-11T12:13:16.303 回答
6

如果我问你“你是用自己开发的语言编写商业软件吗?还是你自己挖井后喝水?”

这就是通过创建线程并管理它们来编写多线程的区别,而您可以使用 TPL 对线程进行抽象。多核和内核上的线程调度由操作系统维护,因此您无需担心您的线程是否在您的系统支持 AFAIK 的内核上执行。

于 2013-03-11T05:47:45.883 回答
2

查看这篇文章,它基本上总结了在 TPL 之前(几乎)不可能的事情,尽管许多公司已经酿造了自己的并行处理库,但它们都没有经过充分优化以利用流行架构的所有资源(仅仅是因为它很大)任务和微软有很多资源+他们很好)。另外有趣的是英特尔的对应实现TBB与 TPL

于 2013-03-11T05:49:33.690 回答
2

这是否意味着使用早期版本的 .NET 无法实现多核和并行编程应用程序?

一点也不。自 .Net 1 以来,就出现了 和 等类型ThreadThreadPool用于在其他线程上调度计算以及ManualResetEvent用于同步。

我是否控制 .NET 多线程应用程序中内核之间的多核/并行使用/分布?

不,这主要是操作系统的工作。您可以设置ProcessorAffinitya ProcessThread,但没有简单的方法ProcessThread从 a 获取 a Thread(因为最初认为 .NetThread可能不直接对应于 OS 线程)。通常没有理由这样做,你尤其不应该为ThreadPool线程这样做。

.NET 4.0+ 任务并行库启用了哪些在以前的 .NET 版本中无法做到的事情?

我会说这并没有使任何不可能成为可能。但它使许多任务变得更加简单。

您始终可以编写自己的版本ThreadPool并手动使用同步原语(如ManualResetEvent)在线程之间进行同步。但是正确有效地做到这一点是很多容易出错的工作。

.NET 中开发多线程应用程序和并行编程有什么区别?

这只是一个命名问题,与你之前的问题没有太大关系。并行编程意味着同时执行多个操作,但并没有说明如何实现并行性。为此,您可以使用多台计算机、多个进程或多个线程,甚至一个线程。

(如果操作不受 CPU 限制,则可以在单线程上进行并行编程,例如从磁盘读取文件或从 Internet 获取一些数据。)

因此,多线程编程是并行编程的一个子集,尽管它在 .Net 上最常用。

于 2013-03-11T12:07:31.930 回答
1

多线程过去可以在单核 CPU 上使用。我相信在 .NET 世界中,“并行编程”代表编译器/语言,以及命名空间和“库”添加,它们促进了多核功能(比以前更好)。从这个意义上说,“并行编程”是多线程下的一个类别,它为多个 CPUa/内核提供了改进的支持。

我自己的思考:同时我看到.NET“并行编程”不仅包含多线程,还包含其他技术。考虑一下新的 async/await 设施不保证多线程的事实,因为在某些情况下,它们只是可以在单个线程上完成所有事情的持续传递样式范式的抽象。包括来自运行不同进程(可能在不同机器上)的混合并行性,从这个意义上说,多线程只是“并行编程”这个更广泛概念的一部分。

但是,如果您考虑 .NET 版本,我认为前者是一个更好的解释。

于 2013-03-11T07:09:53.290 回答