c++ - 多线程会提供任何性能提升吗?

标签 c++ performance multithreading cpu ram

我一般是编程新手,所以在回答我的问题时请记住这一点。

我有一个程序,它采用一个大型 3D 数组(10 亿个元素)并将沿各个轴的元素相加,以生成数据每一侧的投影的 2D 数组。这里的问题是它对内存非常密集,因为程序不断地从内存中获取信息,包括读取和写入。

问题是,如果我对程序进行多线程处理,我会获得任何性能提升,还是最终会遇到 RAM 访问瓶颈?当我说多线程时,我只是指 2 或 4 核的多线程,仅此而已。

如果有帮助,我当前的计算机配置是 2.4ghz core2 quad、1033 fsb、4gb ram at 667mhz。

提前致谢,

-伪造

编辑:

在我看来,这里的人们对我最初预期的这个问题更感兴趣。我将扩展问题并为感兴趣的人发布一些代码。

首先,了解一下我的背景,以便您了解我来自哪里。我是一名机械工程研究生,他设法选择了一个与机械工程几乎无关的主题。大约 5 年前,我参加了 1 门 Java 入门类(class)(强制),直到大约一个月前我认真开始我的论文时才接触过编程。我还参加了(再次被迫,仍然不知道为什么)电子和计算机工程类(class),我们处理了微 Controller (8 位)、它们的内部工作原理以及它们的一些 ASM 编码。除此之外,我对编程几乎一无所知。

代码如下:

int dim = 1000;
int steps = 7 //ranges from 1 to  255

for (int stage = 1; stage < steps; stage++)
for (int j = 0; j < dim; j++)
    for (int i = 0; i < dim; i++)
    {
        sum = 0;
        for (int k = 0; k < dim; k++)
            if (partMap[(((i * dim) + k) * dim) + j] >= stage)
                sum++;

        projection[(j*dim) + i] = sum;
    } 

这部分代码仅在 z 轴上运行。主要数据,由于它的构造方式,有一个奇怪的寻址系统,但你不必担心。还有其他代码用于投影立方体的其他面,但它们做的事情非常不同。

最佳答案

跨多个内核的多线程可以减少跨轴求和所需的时间,但需要特别小心。实际上,您可以对单线程代码进行一些更改,从而获得更大的性能提升:

  1. 您只需要尽可能多的线程来匹配您可用的内核数量。这是一个 CPU 密集型操作,线程不太可能等待 I/O。

  2. 如果整个数组无法放入 RAM,上述假设可能不成立。如果数组的某些部分被分页进出,一些线程将等待分页操作完成。在这种情况下,程序可能会受益于拥有比内核更多的线程。但是,太多了,性能会由于上下文切换的成本而下降。您可能需要尝试线程数。一般规则是尽量减少就绪线程之间的上下文切换次数。

  3. 如果整个数组都无法放入 RAM,您希望尽量减少分页!每个线程访问内存的顺序很重要,所有正在运行的线程的内存访问模式也很重要。在可能的情况下,您会希望在移动到下一个部分之前完成阵列的一部分,永远不要返回被覆盖的区域。

  4. 每个核心都将受益于必须访问一个完全独立的内存区域。您希望避免由锁和总线争用引起的内存访问延迟。至少对于多维数据集的一个维度,这应该很简单:为每个线程设置其自己的多维数据集部分。

  5. 相对于从 RAM 中获取数据,每个内核也将从其缓存中访问更多数据中受益。这意味着对循环进行排序,以便内部循环访问附近的单词,而不是跳过行。

  6. 最后,根据数组中的数据类型,Intel/AMD 处理器(SSE,不同代)的 SIMD 指令可以通过一次对多个单元求和来帮助加速单核性能。 VC++有一些built in support .

  7. 如果您必须确定工作的优先级,您可能希望首先尽量减少磁盘分页,然后集中精力优化内存访问以利用 CPU 缓存,然后再处理多线程。

关于c++ - 多线程会提供任何性能提升吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1106481/

相关文章:

C#:为什么函数调用比手动内联更快?

linux - 如何使用 strace 跟踪子进程?

java - Java 中的简单多线程

c++ - 如何使用 boost ptree 删除 xml 属性?

C++ 自定义分配器

windows - 如何解释这种非常慢的套接字连接?

r - 是否有更快的方法来合并数据帧并循环组合?

c++ - 如何让字符串输入n次?

c++ - 混合 C++ 标准字符串和 Windows API

线程间的Java通信