C++ 多线程与多处理
我是这种编程新手,需要你的观点 我必须构建一个应用程序,但我不能让它计算得足够快。我已经尝试过Intel TBB,它很容易使用,但我从未使用过其他库 在多处理器编程中,我正在阅读有关OpenMP和Boost的多线程技术,但我不知道它们的优缺点C++ 多线程与多处理,c++,multithreading,parallel-processing,multiprocessing,C++,Multithreading,Parallel Processing,Multiprocessing,我是这种编程新手,需要你的观点 我必须构建一个应用程序,但我不能让它计算得足够快。我已经尝试过Intel TBB,它很容易使用,但我从未使用过其他库 在多处理器编程中,我正在阅读有关OpenMP和Boost的多线程技术,但我不知道它们的优缺点 在C++中,多线程编程何时与多处理器编程相比是有利的,反之亦然?哪种方法最适合于繁重的计算或启动许多任务?当我们构建用它们设计的应用程序时,它们的优缺点是什么?最后,哪个库最适合使用?多线程的意思就是运行多个线程。这可以在单处理器系统或多处理器系统上完成
在C++中,多线程编程何时与多处理器编程相比是有利的,反之亦然?哪种方法最适合于繁重的计算或启动许多任务?当我们构建用它们设计的应用程序时,它们的优缺点是什么?最后,哪个库最适合使用?多线程的意思就是运行多个线程。这可以在单处理器系统或多处理器系统上完成 在单处理器系统上,当运行多个线程时,对计算机同时执行多个任务(即多任务)的实际观察是一种错觉,因为真正发生在引擎盖下的是有一个软件调度器在单CPU上执行时间切片。因此,在任何给定的时间只有一个任务发生,但调度程序在任务之间切换的速度足够快,因此您永远不会注意到有多个进程、线程等在争夺同一CPU资源 在多处理器系统上,减少了时间切片的需要。时间切片效应仍然存在,因为现代操作系统可能有数百个线程争夺两个或更多处理器,而且线程数量与可用处理内核数量之间通常不存在1对1的关系。因此,在某个时刻,一个线程必须停止,另一个线程在两个线程共享的CPU上启动。这同样由操作系统的调度程序处理。也就是说,与单处理器系统不同,多处理器系统可以同时发生两件事情
最后,这两种范式在某种意义上确实是正交的,即当您想要异步运行两个或多个任务时,就需要多线程,但由于时间切片,您不一定需要多处理器系统来完成这一点。如果您正在尝试运行多个线程,并且正在执行高度并行的任务(即,尝试求解整数),那么是的,您可以在一个问题上抛出的内核越多越好。您不一定需要线程和处理内核之间的1对1关系,但同时,您也不希望剥离太多线程,最终导致大量空闲线程,因为它们必须等待在一个可用的CPU内核上进行调度。另一方面,如果并行任务需要某些顺序组件,即一个线程将等待另一个线程的结果,然后才能继续,那么您可以使用某种类型的屏障或同步方法运行更多线程,以便需要空闲的线程不会使用CPU时间旋转,只有需要运行的线程在争夺CPU资源。回答第一个问题: 最好的方法是在代码中只使用多线程技术,直到您达到这样的程度,即使这样也不会给您带来足够的好处。假设操作系统将处理委托给多个处理器(如果它们可用) 如果您实际上正在处理一个多线程还不够的问题,即使使用多个处理器(或者如果您运行的操作系统没有使用多个处理器),那么您可能会担心如何获得更多的功能。这可能意味着通过网络将进程衍生到其他机器
我没有使用TBB,但是我使用了IPP,并且发现它是高效的和设计良好的。Boost是可移植的。我认为@Jason的优秀答案中应该添加一些要点 首先,即使在单个处理器上,多线程也不总是一种幻觉——有些操作并不涉及处理器。这些主要是I/O磁盘、网络、终端等。此类操作的基本形式是阻塞或同步,即您的程序等待操作完成,然后继续。等待时,CPU切换到另一个进程/线程 如果您在这段时间内有任何可以做的事情(例如等待用户输入时的后台计算、服务另一个请求等),您基本上有两个选择:
- 使用异步I/O:调用非阻塞I/O,为其提供回调函数,告诉它“完成后调用此函数”。调用立即返回,I/O操作在后台继续。你继续做其他的事情
- 使用多线程:每种任务都有一个专用线程。当一个等待阻塞I/O调用时,另一个继续
- 使用异步I/O时,程序逻辑的逻辑不太明显,难以遵循和调试。但是,您可以避免线程安全问题
- 对于线程,挑战在于编写程序。线程安全性故障是很难重现的严重错误。过度使用锁定实际上会导致性能下降,而不是提高性能