多线程与多处理

Naz*_*zka 30 c++ parallel-processing multithreading multiprocessing

我是这种编程的新手,需要你的观点.

我必须构建一个应用程序,但我无法让它足够快地进行计算.我已经尝试过英特尔TBB,它很容易使用,但我从未使用过其他库.

在多处理器编程中,我正在阅读有关多线程的OpenMP和Boost,但我不知道它们的优缺点.

在C++中,与多处理器编程相比,何时多线程编程是有利的,反之亦然?哪个最适合于繁重的计算或启动许多任务......?当我们构建使用它们设计的应用程序时,它们的优缺点是什么?最后,哪个库最适合使用?

Jas*_*son 55

多线程意味着,运行多个线程.这可以在单处理器系统或多处理器系统上完成.

在单处理器系统上,当运行多个线程时,实际观察计算机同时执行多项操作(即多任务处理)是一种错觉,因为真正发生的事情是有一个软件调度程序在单个CPU上执行时间分片.因此,在任何给定时间只发生一个任务,但调度程序在任务之间切换得足够快,以至于您从未注意到有多个进程,线程等争用相同的CPU资源.

在多处理器系统上,减少了对时间分片的需求.时间切片效应仍然存在,因为现代操作系统可能有数百个线程竞争两个或更多处理器,并且线程数与可用处理核心数之间通常不存在一对一的关系.所以在某些时候,线程必须停止,另一个线程在两个线程共享的CPU上启动.这再次由OS的调度程序处理.话虽如此,通过多处理器系统,您可以同时发生两件事,与单处理器系统不同.

最后,这两个范例在某种程度上是正交的,因为每当你想让两个或多个任务异步运行时你就需要多线程,但是由于时间切片,你不一定需要一个多处理器系统来完成那.如果您正在尝试运行多个线程,并且正在执行高度并行的任务(即尝试解决积分),那么是的,您可以在问题上投入的核心越多越好.您不一定需要线程和处理核心之间的一对一关系,但同时,您不希望剥离这么多线程,最终导致大量空闲线程,因为它们必须等待安排在其中一个可用的CPU核心上.另一方面,如果您的并行任务需要一些顺序组件,即一个线程将在另一个线程继续之前等待来自另一个线程的结果,那么您可能能够使用某种类型的屏障或同步方法运行更多线程,需要空闲的线程不使用CPU时间旋转,只有需要运行的线程争用CPU资源.

  • 你打字快!我只想加上我的两分钱作为评论. (3认同)

dav*_*vka 21

我认为应该在@Jason的优秀答案中加入一些重要的观点.

首先,即使在单个处理器上,多线程也不总是一种错觉 - 有些操作不涉及处理器.这些主要是I/O--磁盘,网络,终端等.此类操作的基本形式是阻塞同步,即程序等待操作完成然后继续.在等待时,CPU切换到另一个进程/线程.

如果您在此期间可以做任何事情(例如,在等待用户输入时进行背景计算,提供其他请求等),您基本上有两种选择:

  • 使用异步I/O:你调用一个非阻塞 I/O,为它提供一个回调函数,告诉它"当你完成时调用这个函数".该调用立即返回,I/O操作在后台继续.你继续其他的东西.

  • 使用多线程:您有针对每种任务的专用线程.当一个人等待阻止I/O呼叫时,另一个继续.

这两种方法都是困难的编程范式,每种方法都有其优缺点.

  • 对于异步I/O,程序逻辑的逻辑不太明显,难以跟踪和调试.但是,您可以避免线程安全问题.
  • 对于线程,challange是编写线程安全的程序.线程安全故障是非常难以重现的令人讨厌的错误.锁定的过度使用实际上可能导致降级而不是改善性能.

(来到多处理)

多线程在Windows上很流行,因为在Windows上操作流程非常繁重(创建进程,上下文切换等)而不是线程更轻量级(至少在我使用Win2K时就是这种情况).

在Linux/Unix上,进程更轻量级.Linux上的(AFAIK)线程实际上也是内部实现的一种进程,因此线程与进程的上下文切换没有任何好处.但是,您需要使用某种形式的IPC(进程间通信),如共享内存,管道,消息队列等.

更简单的说明,请查看SQLite FAQ,它声明"线程是邪恶的"!:)

  • 还有第三种选择,通过select()/ poll()/ etc复用I/O. 这比多线程更安全,比异步I/O更容易理解. (2认同)

Mik*_*e C 5

回答第一个问题:最好的方法是在代码中使用多线程技术,直到达到这样的程度,即使这样也无法给您带来足够的好处。假设操作系统将处理对多个处理器的委派(如果可用)。

如果您实际上正在解决多线程还不够的问题,即使有多个处理器(或者如果您正在不使用多个处理器的操作系统上运行),那么您可能会担心如何获得更多功能。这可能意味着通过网络将进程生成到其他机器。

我没有使用过 TBB,但我使用过 IPP,发现它高效且设计精良。Boost 是便携式的。