具有“k”线程运行的多线程程序能否比其顺序版本快“k”倍以上?
Can a multithread program with `k` threads run more than `k` times faster than its sequential version?
我知道并行程序的瓶颈,包括导致多线程程序 运行 比我们预期的 运行ning 时间慢,甚至比其顺序版本慢的内存访问速度限制.我想知道是否可以反过来(解释如下)。
具体来说,我想知道是否存在这样一种情况,其中具有 k
个线程 运行 的多线程程序比程序的顺序版本快 k
倍以上同一台机器。假设程序的顺序版本需要 100 秒来完成任务,而使用 5 个线程的多线程版本需要 10 秒才能完成。
我假设这两个程序具有相同的算法、相同的数据结构、相同的实现以及具有相同优化选项的相同编译器。
一种可能的情况是硬件可以更好地执行多线程程序,但我不知道这样的硬件(问题是是否存在)。另一种情况可能是较低级别的软件实现。例如编译器对多线程版本有更好的优化,但是在真实的编译器中有这样的情况吗?
编辑:这个答案的一个迹象是据说 AMD 在多线程任务上表现更好,而不是在单线程任务上。但它是如何完成的呢? (Difference between intel and AMD multithreading)
不太可能,但在线程切换成本高而线程间通信成本低的系统上可能性很小。这当然很少见,这两种操作的性能通常是相关的。
绝对有可能。我能想到的一种情况是当程序是
- I/O-bound rather than CPU-bound 和
- I/O 子系统的缓慢被随机数据访问模式放大,这混淆了 pefetching 启发式。
在这种情况下,程序的单线程版本经常停滞,直到 I/O 子系统(从 RAM、磁盘、数据库等)提供必要的数据。在多线程的情况下,不同线程的随机数据访问可能会交错形成一个完全可预测的模式(例如,理想的顺序访问),这使得预取启发式可以按顺序提高 I/O 子系统的吞吐量幅度,几乎完全消除了 I/O 等待时间。
虽然这种奇怪的加速可能是不同线程之间幸运时序的结果,但实际上并不是由于引入了多线程本身,而是可以通过优化数据访问效率的算法来更确定地实现。然而,在某些情况下,更容易引入一个模拟真实工作线程数据访问模式的辅助线程,并让辅助线程运行(作为一个消息灵通的预取器)稍微领先于工作线程,这样后者不必等待数据。在那些情况下,由于所描述的效果,多线程可以被视为加速程序的真正工具。
我知道并行程序的瓶颈,包括导致多线程程序 运行 比我们预期的 运行ning 时间慢,甚至比其顺序版本慢的内存访问速度限制.我想知道是否可以反过来(解释如下)。
具体来说,我想知道是否存在这样一种情况,其中具有 k
个线程 运行 的多线程程序比程序的顺序版本快 k
倍以上同一台机器。假设程序的顺序版本需要 100 秒来完成任务,而使用 5 个线程的多线程版本需要 10 秒才能完成。
我假设这两个程序具有相同的算法、相同的数据结构、相同的实现以及具有相同优化选项的相同编译器。
一种可能的情况是硬件可以更好地执行多线程程序,但我不知道这样的硬件(问题是是否存在)。另一种情况可能是较低级别的软件实现。例如编译器对多线程版本有更好的优化,但是在真实的编译器中有这样的情况吗?
编辑:这个答案的一个迹象是据说 AMD 在多线程任务上表现更好,而不是在单线程任务上。但它是如何完成的呢? (Difference between intel and AMD multithreading)
不太可能,但在线程切换成本高而线程间通信成本低的系统上可能性很小。这当然很少见,这两种操作的性能通常是相关的。
绝对有可能。我能想到的一种情况是当程序是
- I/O-bound rather than CPU-bound 和
- I/O 子系统的缓慢被随机数据访问模式放大,这混淆了 pefetching 启发式。
在这种情况下,程序的单线程版本经常停滞,直到 I/O 子系统(从 RAM、磁盘、数据库等)提供必要的数据。在多线程的情况下,不同线程的随机数据访问可能会交错形成一个完全可预测的模式(例如,理想的顺序访问),这使得预取启发式可以按顺序提高 I/O 子系统的吞吐量幅度,几乎完全消除了 I/O 等待时间。
虽然这种奇怪的加速可能是不同线程之间幸运时序的结果,但实际上并不是由于引入了多线程本身,而是可以通过优化数据访问效率的算法来更确定地实现。然而,在某些情况下,更容易引入一个模拟真实工作线程数据访问模式的辅助线程,并让辅助线程运行(作为一个消息灵通的预取器)稍微领先于工作线程,这样后者不必等待数据。在那些情况下,由于所描述的效果,多线程可以被视为加速程序的真正工具。