2011-10-03 56 views
3

我的,我要处理相当大的文件,这让我思考一个小名单...多线程是否等于少CPU?

在C#中,我在考虑使用第三方物流的Parallel.ForEach利用现代多核CPU的,但我的问题更多的是一个假设的性格;

在实际中使用多线程是否意味着并行加载文件需要更长的时间(尽可能多地使用CPU内核),而不是按顺序加载每个文件(但CPU可能更少) -utilization)?

或者换用另一种方式(?:

什么是多线程的点更多的任务并行,但以较慢的速度,而不是集中在一个任务中的所有计算资源在同一时间?

回答

3

你问多个问题,所以我已经打破了我的响应分为多个答案:

  1. 多线程可能对加载速度没有影响,这取决于装载在你的瓶颈是什么。如果您从磁盘或数据库加载大量数据,则I/O可能是您的限制因素。另一方面,如果“加载”涉及使用一些数据执行大量CPU工作,那么使用多线程可能会加快速度。

  2. 一般而言,您无法将“所有计算资源集中在一项任务上”。某些多核处理器有能力超频单核以换取其他内核的禁用,但这种速度提升并不等于您通过使用多线程/多处理技术充分利用所有内核而获得的潜在性能优势。换句话说,它是不对称的 - 如果你有一个4核心的1Ghz CPU,它将无法将单个核心超频到4ghz,以换取禁用其他核心。事实上,这就是业界首先进行多核的原因 - 至少现在我们已经限制了单CPU运行的速度,所以我们已经走了增加更多CPU的路线。

  3. 多线程有两个原因。首先是你想要同时运行任务,只是因为它们都希望能够同时发生 - 例如,你希望你的图形用户界面继续响应点击或键盘按下,而它正在做其他工作(事件循环是另一种方式来实现这一点)。其次是利用多个内核来提升性能。

4

为了在不增加延迟,并行计算程序通常只能创建每个核心一个线程。应用,这不是纯粹的计算往往会添加更多的线程,以便运行的线程数是(其余为内核的数量在I/O等待,而不是相互竞争的CPU时间)。

现在,磁盘I /○b并行ound程序可能会导致性能下降,若磁盘有一个不可忽略的寻道时间则多得多的时间将被浪费执行寻求和实际阅读的时间较少。这被称为“搅动”或“颠簸”。电梯分类有所帮助,真正的随机存取(如固态存储器)有助于更多。并行性几乎总是会增加所完成的原始工作量,但这只有在电池寿命是最重要的时候才是重要的(当您考虑其他组件使用的功率时,比如屏幕背光,更快地完成往往总体上效率更高)。

+0

现在看来CPU可以在每个内核基础上进行频率调整,因此避免线程“节省”电池寿命的意义更小。 –

+0

@JosephGarvin:我不相信每个内核的频率是受支持的。从功耗的角度来看,关闭次级内核的能力有利于单线程的情况(非并行更有效 - 没有缓存冲突,不分割缓存,也没有同步逻辑)。 –

+0

我知道每个核心频率都被支持,因为我的Thinkpad 410s会这么做:)或者gnome频率监视器applet被窃听。我看到它显示出1或2个核心,而没有其他所有的核心。 –

2

多线程是高度并行的任务非常有用。 CPU密集型任务是完美的。你的CPU有很多内核,许多线程可以使用多个内核。他们会使用更多的CPU时间,但最终他们会使用更少的“用户”时间。如果您的应用I/O为界,那么多线程并不总是溶液(但它可以帮助)

3

用于从磁盘加载文件,这很可能使事情慢。操作系统会尝试将文件放置在磁盘上,这样您就只需要为每个文件执行一次昂贵的磁盘查找操作。如果你有很多线程读了很多文件的,你要去争过哪个线程可以访问磁盘,你必须每下一个线程获得一个时间寻求回到正确的位置在文件中转。

你可以做的只是使用两个线程。设置一个加载后台中的所有文件,并让其他任务可用于处理用户输入等其他任务。在C#winforms中,您可以使用BackgroundWorker控件轻松完成此操作。

+0

同意第一部分,但第二部分适用于'平时'。如果文件需要CPU进行大量处理,则可以使用更多线程,但只能使用1个(每个磁盘)来进行读取。 –

+0

@亨克 - 如果他们需要更长的时间处理而不是阅读,他们需要大量的处理。但即使在这种情况下,您几乎总是仍然希望尽可能快地按顺序读取文件,并使用生产者/消费者队列来处理处理,以便您可以尽可能快地从一个文件中读取文件并将工作项目排队等待其他线程处理。 –

0

正如所有伟大的编程努力,这取决于。总的来说,您将从一个实体商店或一个物理控制器请求文件,这会无论如何(或者更糟糕的是,会在经典硬盘驱动器上产生大量头部来回)将请求序列化,并减慢已经存在的速度慢I/O。

OTOH,如果控制器和介质是分开的,多个内核从它们加载数据应该通过顺序方法改进。