如何衡量多线程代码如何扩展(加速)?

时间:2012-03-09 22:47:32

标签: c++ multithreading profiling parallel-processing

假设我只有4个内核,那么衡量程序加速的最佳方法是什么?显然我可以测量到4,但是知道8,16等等会很好。

理想情况下,我想知道每个线程数的加速量,类似于此图:

Amdahl's law diagram

我有什么方法可以做到这一点?也许是一种模拟多核的方法?

5 个答案:

答案 0 :(得分:3)

我很抱歉,但在我看来,唯一可靠的衡量标准是实际获得8,16或更多核心机器并对其进行测试。

内存带宽饱和,CPU功能单元数量和其他硬件瓶颈会对可扩展性产生巨大影响。我从个人经验中了解到,如果一个程序在2个核心和4个核心上扩展,那么当在8个核心上运行时,它可能会大大减慢,仅仅因为它不足以让8个核心能够扩展8倍。

您可以尝试预测会发生什么,但需要考虑很多因素:

  1. 缓存 - 大小,图层数,共享/非共享
  2. 内存带宽
  3. 核心数与处理器数量,即8核机器还是双核心机器
  4. 内核之间的互连 - 较少数量的内核(2,4)仍可以很好地与总线配合使用,但对于8个或更多内核,则需要更复杂的互连。
  5. 内存访问 - 同样,较少数量的内核与SMP(对称多处理)模型配合良好,而更多内核需要NUMA(非统一内存访问)模型。

答案 1 :(得分:2)

我认为没有一种真正的方法可以做到这一点,但我想到的一件事是你可以使用虚拟机来模拟更多核心。例如,在VirtualBox中,您可以从标准菜单中选择最多16个核心,但我非常确信有一些黑客可以使更多这样的内容,而像VMware这样的其他VirtualMachines甚至可以支持更多的开箱即用。

enter image description here

答案 2 :(得分:2)

bamboon和doron是正确的,许多变量正在发挥作用,但如果你有一个可调整的输入大小n,你可以找出强缩放弱缩放您的代码。

强缩放是指修复问题大小(例如n = 1M)并改变可用于计算的线程数。弱缩放是指修复问题大小每个线程n = 10k/thread)并改变可用于计算的线程数。

在任何程序中都有很多变量可用 - 但是如果你有一些基本的输入大小n,那么可能会有一些相似的缩放。在我几年前开发的n-body模拟器上,我根据固定大小和每个线程的输入大小改变了线程,并且能够合理地计算出多线程代码缩放程度的粗略度量。

由于您只有4个核心,因此您只能可行地计算最多4个线程的扩展。这严重限制了您查看其对大部分螺纹负载的扩展程度的能力。但如果您的应用程序仅用于核心数量较少的计算机上,则这可能不是问题。

你真的需要问自己一个问题:这是否会用于10,20,40+个线程?如果是这样,准确确定这些制度的缩放的唯一方法是在具有该硬件可用的平台上实际对其进行基准测试。


附注:根据您的应用程序,您可能只有4个核心并不重要。如果许多线程花费时间“等待”某些事情发生(例如,Web服务器),则一些工​​作负载随着线程的增加而扩展,而不管可用核心的实际数量。如果您正在进行纯计算,则情况并非如此

答案 3 :(得分:1)

我不相信这是可能的,因为有太多的变量无法准确地推断性能。即使假设你是100%并行。还有其他因素,如总线速度和缓存未命中,可能会限制您的性能,更不用说周边性能。所有这些因素如何影响您的代码只能通过在特定硬件平台上进行测量来完成。

答案 4 :(得分:1)

我认为你是在询问测量,所以我不会解决预测对更多核心数量的影响的问题。

这个问题可以通过另一种方式来看待:你可以保持每个线程的繁忙程度,以及它们共计的内容是什么?因此,对于六个线程,每个运行的利用率为50%,意味着您有3个等效的处理器在运行。将其除以四个处理器,意味着您的方法实现了75%的利用率。将该利用率与实际加速的时钟时间进行比较,可以告诉您有多少利用率是新的开销,以及实际加速的程度。那不是你真正感兴趣的吗?

处理器利用率可以通过几种不同的方式实时计算。线程可以独立地询问系统的线程时间,计算比率并保持全局总数。如果您完全控制阻塞状态,则甚至不需要系统调用,因为您可以跟踪阻塞与非阻塞机器周期的比率,以计算利用率。我开发的实时多线程仪器包使用这样的方法,它们运行良好。较新的cpu中的cpu时钟计数器读取内部20个机器周期。