我是新手,需要您的建议。
我需要构建一个应用程序,但是我无法让它快速计算。我已经尝试过Intel TBB,它很容易使用,但我从未使用过其他库。
在多处理器编程中,我正在研究OpenMP和Boost用于多线程,但我不知道它们的优缺点。
在C++中,什么时候使用多线程编程比多处理器编程优势更大,反之亦然?在处理繁重计算或启动大量任务时,哪种更适合?当我们使用它们构建应用程序时,它们的优缺点是什么?最后,哪个库最适合工作?
我是新手,需要您的建议。
我需要构建一个应用程序,但是我无法让它快速计算。我已经尝试过Intel TBB,它很容易使用,但我从未使用过其他库。
在多处理器编程中,我正在研究OpenMP和Boost用于多线程,但我不知道它们的优缺点。
在C++中,什么时候使用多线程编程比多处理器编程优势更大,反之亦然?在处理繁重计算或启动大量任务时,哪种更适合?当我们使用它们构建应用程序时,它们的优缺点是什么?最后,哪个库最适合工作?
多线程意味着运行多个线程。这可以在单处理器系统上或多处理器系统上完成。
在单处理器系统上,运行多个线程时,计算机同时执行多个任务(即多任务处理)的实际观察是一种幻觉,因为在幕后的真正情况是,有一个软件调度程序在单个 CPU 上进行时间分片。因此,在任何给定时间,只有一个任务正在运行,但调度程序在任务之间快速切换,以便您从未注意到有多个进程、线程等争用同一 CPU 资源。
在多处理器系统上,需要减少时间分片的需求。时间分片效应仍然存在,因为现代操作系统可能有数百个线程争用两个或更多处理器,并且通常不存在线程数量与可用处理核心数量的1:1关系。因此,在某个时候,一个线程将不得不停止,另一个线程开始在两个线程共享的 CPU 上运行。这也由操作系统的调度程序处理。尽管如此,使用多处理器系统,您可以同时发生两件事情,这与单处理器系统不同。
从本质上讲,这两种范式是有些正交的,因为只要想要有两个或多个任务异步运行,就需要使用多线程,但由于时间片分配,不一定需要一个多处理器系统来完成。如果你试图运行多个线程,并且正在进行高度并行的任务(例如,尝试解决积分),那么是的,你可以将更多的核心投入到问题中。你不一定需要线程与处理器核心之间的1对1关系,但同时,你也不希望启动太多线程,以至于它们必须等待在可用CPU核心上调度而产生大量空闲线程。另一方面,如果你的并行任务需要一些连续组件,即一个线程将在等待另一个线程的结果之后才能继续,那么你可能可以运行更多线程,采用某种障碍或同步方法使需要空闲的线程不会消耗CPU时间,只有需要运行的线程竞争CPU资源。grep
、sed
、cp
等命令行应用程序就不是多线程的。 - Jason我认为应该在@Jason的优秀答案中添加一些重要观点。
首先,即使在单处理器上,多线程并不总是虚幻的 - 有些操作不涉及处理器。主要是I / O - 磁盘,网络,终端等。这种操作的基本形式是阻塞或同步,即您的程序等待操作完成然后继续。等待时,CPU会切换到另一个进程/线程。
如果您在此期间可以做任何事情(例如在等待用户输入时进行后台计算,提供另一个请求等),则基本上有两个选择:
使用异步I / O:调用非阻塞I / O,并向其提供回调函数,告诉它“在完成时调用此函数”。调用立即返回,I/O操作在后台继续。继续进行其他工作。
使用多线程:每种任务都有一个专用线程。当一个线程等待阻塞I / O调用时,另一个线程继续运行。
两种方法都是困难的编程范例,各自都有利弊。
(转向多处理)
在Windows上流行的多线程是因为操作进程在Windows上相当繁重(创建进程,上下文切换等),而线程要轻量得多(至少在我工作的Win2K上是这种情况)。
在Linux / Unix上,进程要轻量得多。此外(据我所知),Linux上的线程实际上是一种内部进程,因此在线程与进程之间进行上下文切换方面没有任何优势。然而,您需要使用某种形式的IPC(进程间通信),例如共享内存、管道、消息队列等。
更有趣的是,请看SQLite FAQ,它宣称“线程是邪恶的”! :)