【问题标题】:Limits of parallelization regarding the core number关于核心数量的并行化限制
【发布时间】:2012-04-07 18:51:02
【问题描述】:

我正在英特尔 i5 核机器上开发一种并行算法,该机器有两个内核、四个线程。

n 定义了我在其上执行计算的矩阵的大小。从下表可以看出,从 1 个线程到 2 个线程的利用率几乎减少了 50%,但 2 个线程和 4 个线程之间几乎没有区别。数字表示经过的秒数

我的编译器是 windows 平台上的 mingw-gcc。我的并行化工具是 openmp。我在并行例程的开头通过omp_set_num_threads(numThreads);定义线程数。

我无法在“真正的”8 核机器上测试算法。在我的 i5 机器上,在 1 个线程上,任务管理器显示使用了总 CPU 功率的 25%。 2 线程时为 50%,4 线程时为 96-99%,符合预期。

那么导致这种情况的原因可能是什么?为什么计算时间没有减半?

并行代码段如下:

    #pragma omp parallel for schedule(guided) shared(L,A) \
    private(i)
    for (i=k+1;i<row;i++){
        double dummy = 0;
        for (int nn=0;nn<k;nn++){
            dummy += L[i][nn]*L[k][nn];
            L[i][k] = (A[i][k] - dummy)/L[k][k];
        }
    }

【问题讨论】:

  • 您的内存可能有限。或者您可能在迭代之间有两个很多依赖项。顺便说一句,这是 Cholesky 分解吗?
  • 您是否比较过独立/私有数组/线程与共享?
  • @Oil Charlesworth 是的,这是 Cholesky 分解算法的一部分。但我不认为我的记忆力有限。当 n=5000 时,计算机使用了我 4 GB 容量中的 362 MB。
  • 粗略地说:如果大部分时间值已经在缓存中,那么使用两个线程而不是一个线程不会带来太多好处;同样,如果瓶颈是内存访问,那么更多线程也无济于事。如果有空闲的内存带宽,线程可能会有所帮助,并且使用线程会导致更多的值被加载到缓存/单位时间内。
  • @Emre Turkoz - 我认为 Oli 是正确的,没有发生足够的计算,所以你可能受到内存带宽的限制。但是,我正在考虑将数组“拆分”为 4 个部分,即访问广泛分开的部分,并在每个部分上使用一个线程。如果有足够的内存带宽并且它受 CPU 限制(我不期望),那么使部件“独立”可能会给硬件提供更好的交错内存加载的机会。老实说,我认为计算与内存访问相比太少了,所以我预计不会有太大变化,但可能值得进行一些测试。

标签: c++ gcc parallel-processing openmp


【解决方案1】:

嗯,你的机器有 2 个内核4 个线程

您只有 2 个核心,因此您不会从 1 到 4 个线程获得 4 倍的加速。

其次,当您扩展到更多线程时,您可能会开始遇到资源争用问题,例如最大化内存带宽。

【讨论】:

  • 但是我应该加快速度,对吧?我的意思是根据任务管理器,它是 50% 与 100% 的 cpu 使用率。所以 4 个线程必须利用一些在 2 个线程情况下空闲的源。
  • 正在获得一些加速。 177.669 -> 162.182 虽然很小,但对于超线程来说这是一个非常典型的数量。如果您发布完整的测试代码,我可以在我的一些机器上运行它:4-core/8-thread, 8-core/8-thread, 16-core/16-thread...
  • 谢谢。我相信我应该租一些 hpc 来测试我的代码的可扩展性。家里的电脑对此一无所知。
  • 除此之外,我想说只要一维适合缓存,您的代码就表现出非常好的局部性。大多数并行化矩阵运算的尝试在一开始就失败了,因为它们在内部循环中跳跃缓存行。
  • 您可能想要尝试的另一件事是在两个循环之外通过L[k][k] 提升除法。 (计算它的倒数,然后在内部循环中进行乘法运算。)这可能会显着加快速度,但对并行化没有帮助。
猜你喜欢
  • 2015-09-21
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 2012-10-31
  • 2016-03-09
  • 1970-01-01
相关资源
最近更新 更多