c++ - 如果我有固定数量的相互独立的计算,多线程是否会显着提高性能?

标签 c++ multithreading performance sdl

我正在编写光线转换游戏引擎。 可以在不知道其他射线的情况下计算每条射线(我只计算距离)。 由于计算之间没有等待时间,我想知道使光线计算多线程化是否值得。 性能是否有可能提升?

最佳答案

如果处理得当,多线程很可能会提高性能。按照您陈述问题的方式,它是多线程的完美候选者,因为计算是独立的,从而将线程之间的协调需求降至最低。

仍然可能无法获得加速,或者可能无法获得预期的全部速度的一些原因可能包括:

1) 瓶颈可能不是片上 CPU 执行资源(例如,ALU 绑定(bind)操作),而是一些共享的东西,例如内存或共享 LLC 带宽。

例如,在某些架构上,单个线程可能会使内存带宽饱和,因此添加更多内核可能无济于事。更常见的情况是单个内核可以饱和一些分数,主内存带宽的 1/N < 1,并且该值大于 1/C,其中 C 是内核数。例如,在 4 芯盒上,一个核心可能会消耗 50% 的带宽。然后,对于内存受限的计算,您将很好地扩展到 2 个内核(使用 100% 的带宽),但几乎没有超出此范围。

核心之间共享的其他资源包括磁盘和网络 IO、GPU、监听带宽等。如果您有超线程平台,此列表会增加以包括共享相同逻辑核心的所有级别的缓存和 ALU 资源物理核心。

2) “理论上”独立的操作之间的“实践中”争论。

您提到您的运营是独立的。通常这意味着它们逻辑上独立 - 它们不共享任何数据(除了可能不可变的输入)并且它们可以写入单独的输出区域。然而,这并不排除任何给定的实现实际上都在进行一些隐藏共享的可能性。

一个典型的例子是错误共享——自变量落在同一个缓存行中,因此逻辑上独立的从不同线程写入不同的变量最终会破坏内核之间的缓存行。

在实践中经常遇到的另一个例子是通过库进行争用 - 如果您的例程大量使用 malloc,您可能会发现所有线程大部分时间都在等待分配器内的锁,因为 malloc 是共享资源。这可以通过减少对 malloc 的依赖(可能通过更少、更大的 malloc)或使用良好的并发 malloc(例如 hoard 或 tcmalloc)来补救。

3) 跨线程实现计算的分发和收集可能会压倒您从多线程获得的优势。例如,如果您为每条单独的光线启动一个新线程,线程创建开销将主导您的运行时,您可能会看到负面 yield 。即使您使用持久线程的线程池,选择粒度太细的“工作单元”也会带来大量协调开销,这可能会抵消您的优势。

同样,如果您必须将输入数据复制到工作线程或从工作线程复制输入数据,您可能看不到预期的缩放。在可能的情况下,对只读数据使用按引用传递。

4) 您没有超过 1 个核心,或者您有超过 1 个核心但它们已经被其他线程或进程占用。在这些情况下,协调多个线程的工作是纯粹的开销。

关于c++ - 如果我有固定数量的相互独立的计算,多线程是否会显着提高性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25370160/

相关文章:

C++:如何决定是按引用还是按值传递参数?

.net - 通过使用 .NET 读取/写入 XML 进行数据处理

c - C 中的多线程使用线程安全随机数

performance - 过度使用lucene好吗?

android - 使用 sqlite 将字符串中的单词替换为另一个单词

android - 应用程式在第一次执行的前15秒空白

.net - 将透明 png 图像转换为位图时,它不保留透明度?

c++ - 不能修改零吗?

用于多线程批量导入的Java框架

java - 如何将进度值从线程传递到 Activity ?