我是这种编程的新手,需要你的观点。
我必须构建一个应用程序,但我无法让它足够快地进行计算。我已经尝试过英特尔TBB,它易于使用,但我从未使用过其他库。
在多处理器编程中,我正在阅读关于多线程的OpenMP和Boost,但我不知道它们的优缺点。
在C ++中,与多处理器编程相比,何时多线程编程是有利的,反之亦然?哪种最适合于繁重的计算或启动许多任务......?当我们构建使用它们设计的应用程序时,它们的优缺点是什么?最后,哪个库最适合使用?
答案 0 :(得分:54)
多线程意味着,运行多个线程。这可以在单处理器系统或多处理器系统上完成。
在单处理器系统上,当运行多个线程时,实际观察计算机同时执行多项操作(即多任务处理)是一种幻觉,因为真正发生在幕后的是有软件调度程序在单个CPU上执行时间分片。因此,在任何给定时间只发生一个任务,但调度程序在任务之间切换得足够快,以至于您从未注意到有多个进程,线程等争用相同的CPU资源。
在多处理器系统上,减少了对时间分片的需求。时间切片效应仍然存在,因为现代操作系统可能有数百个线程竞争两个或更多处理器,并且线程数与可用处理核心数之间通常不存在一对一的关系。所以在某些时候,线程必须停止,另一个线程在两个线程共享的CPU上启动。这再次由OS的调度程序处理。话虽如此,使用多处理器系统,可以同时发生两件事,与单处理器系统不同。
最后,这两个范例在某种程度上是正交的,因为每当你想让两个或多个任务异步运行时你就需要多线程,但是由于时间切片,你不一定需要一个多处理器系统来实现这一目标。如果您正在尝试运行多个线程,并且正在执行高度并行的任务(即尝试解决积分),那么是的,您可以在问题上投入的核心越多越好。您不一定需要线程和处理核心之间的一对一关系,但同时,您不希望剥离这么多线程,最终导致大量空闲线程,因为它们必须等待安排在其中一个可用的CPU核心上。另一方面,如果您的并行任务需要一些顺序组件,即一个线程将在另一个线程继续之前等待来自另一个线程的结果,那么您可能能够使用某种类型的屏障或同步方法运行更多线程,需要空闲的线程没有使用CPU时间旋转,只有需要运行的线程争用CPU资源。
答案 1 :(得分:21)
我认为应该在@Jason的优秀答案中添加一些重要的观点。
首先,即使在单个处理器上,多线程并不总是错觉 - 有些操作不涉及处理器。这些主要是I / O - 磁盘,网络,终端等。此类操作的基本形式是 阻止 或 同步 ,即您的程序等待操作完成然后继续。在等待时,CPU切换到另一个进程/线程。
如果您在此期间可以做任何事情(例如,在等待用户输入时进行背景计算,提供其他请求等),您基本上有两种选择:
使用异步I / O :您调用非阻塞 I / O,为其提供回调函数,告诉它“完成后调用此功能”。该调用立即返回,I / O操作在后台继续。你继续其他的东西。
使用多线程:您有针对每种任务的专用线程。当一个人等待阻止I / O呼叫时,另一个继续。
这两种方法都是困难的编程范式,每种方法都有其优点和缺点。
(进入多处理)
多线程在Windows上很受欢迎,因为操作进程在Windows上非常繁重(创建进程,上下文切换等),而不是线程更轻量级(至少在我使用Win2K时就是这种情况)。
在Linux / Unix上,进程更轻量级。 Linux上的(AFAIK)线程实际上也是内部实现的一种进程,因此线程与进程的上下文切换没有任何好处。但是,您需要使用某种形式的IPC(进程间通信),如共享内存,管道,消息队列等。
更简单的说明一下,看看SQLite FAQ,它宣称“线程是邪恶的”! :)
答案 2 :(得分:3)
回答第一个问题: 最好的方法是在代码中使用多线程技术,直到达到甚至没有给你足够好处的程度。假设操作系统将处理授权给多个处理器(如果它们可用)。
如果您确实在处理多线程不够的问题,即使使用多个处理器(或者如果您在不使用其多处理器的操作系统上运行),那么您可以担心发现如何获得更多力量。这可能意味着通过网络向其他计算机生成进程。
我没有使用TBB,但我使用过IPP,发现它效率高,设计精良。 Boost是便携式的。
答案 3 :(得分:0)
只是想提一下,基于流程的编程(http://www.jpaulmorrison.com/fbp)范例是一种自然的多编程/多处理应用程序开发方法。它提供从高级到低级的一致应用程序视图。 Java和C#实现利用了计算机上的所有处理器,但旧的C ++实现仅使用一个处理器。但是,通过使用锁定连接,可以相当容易地扩展为使用BOOST(或pthreads,我假设)。我已经开始将其转换为使用光纤,但我不确定是否继续这条路线是否有任何意义。 :-)反馈将不胜感激。 BTW Java和C#实现甚至可以使用套接字进行相互通信。
答案 4 :(得分:0)
多处理正在向系统中添加更多数量的CPU /处理器,从而提高了系统的计算速度。
多线程允许进程创建更多线程,从而增加系统的响应速度
多处理
多处理系统是具有两个以上处理器的系统。将CPU添加到系统中以提高系统的计算速度。每个CPU都有自己的一组寄存器和主存储器。仅仅因为CPU是分开的,可能会发生一个CPU不能处理任何东西而闲置的情况,而另一个CPU可能使这些进程超载。在这种情况下,进程和资源将在处理器之间动态共享
多线程
进程的线程是指进程的代码段,它具有自己的线程ID,程序计数器,寄存器和堆栈,并且可以独立执行。但是属于同一个进程的线程必须共享该进程的所有东西,例如代码,数据和系统资源。为每个服务请求创建单独的流程会浪费时间并浪费系统资源。与其产生这种开销,不如创建一个进程的线程
多线程和多处理
之间的比较很小多处理增加了CPU以提高计算能力,多线程创建了单个进程的多个线程以增加计算能力
多重处理,多个进程同时执行。在多线程中,单个进程的多个线程是同时执行的。
多重处理,创建一个过程既耗时又浪费资源。在多线程中,创建线程在时间和资源上都是经济的。
多重处理可以是对称的或不对称的。多线程未分类。