【问题标题】:For loop doen't speed up after gcc -O3 optimizition using OpenMP [duplicate]使用 OpenMP 进行 gcc -O3 优化后,for 循环不会加速 [重复]
【发布时间】:2016-02-23 15:14:53
【问题描述】:

我编写了一个简单的 for 循环,它将一个常量分配给一个数组。

#include <iostream>
#include <vector>
#include <cstdlib>

#include "omp.h"

using namespace std;
int nr_threads = 1;
long J = 10000000;
long K = 40;

int main(int argc, char* argv[])
{
    nr_threads = atoi(argv[1]);
    vector<double> H_U_d(J*K, 1);

    double start_time = omp_get_wtime();
#pragma omp parallel for num_threads(nr_threads) schedule(static)
    for(long j = 0; j < J*K; j++)
    {
            H_U_d[j] = 1;
    }
    cout << omp_get_wtime()-start_time << endl;
    return 0;
}

我使用 gcc 编译它,g++ main.cpp -o test_speedup -fopenmp 并在 12 核机器上测试它。 我的系统是 Ubuntu 14.04.3,cpu 是 Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz 和 128GB RAM。 如果不进行优化,我们可以得到这样的结果:

➜ ~ ./test_speedup 1

2.95739

➜ ~ ./test_speedup 8

0.483756

加速约为 6。

但是如果我使用 -O3 来优化它,g++ main.cpp -o test_speedup -fopenmp -O3

结果是

➜ ~ ./test_speedup 1

0.379158

➜ ~ ./test_speedup 8

0.265842

加速很差。

gcc 如何优化循环?有什么解决方案可以避免这种情况吗?

【问题讨论】:

  • OpenMP 花一些时间来创建线程。尝试运行时间更长的测试。
  • 优化的单线程循环已经非常优化了,可能会使用 SIMD 指令来加速。当代码已经是最佳时,添加线程根本没有太大帮助。我建议您检查汇编代码并在汇编级别上比较未优化和优化的代码。
  • 如果您想了解编译器在做什么,您可以从查看生成的程序集开始。 gcc -S 在源代码上或 objdump -d 在二进制文件上。

标签: c++ gcc parallel-processing openmp compiler-optimization


【解决方案1】:

您的向量H_U_d 不适合您的处理器的缓存。因此,您的性能可能会受到主内存带宽的限制。在主内存带宽被工作线程饱和后,更多的线程将不得不等待内存。

如果您在多插槽机器上运行,您也可能会遇到一些 numa-effects。更具体的答案需要更多关于我们系统(处理器、内存、操作系统)的信息。

【讨论】:

  • 感谢您的建议,我已经添加了我的系统信息。
  • @user1221244 你知道具体的内存配置吗(频率、双/四通道配置)。请注意,这是一个 6 核 CPU(12 个硬件线程)。 8 线程将是一个特别糟糕的配置。试试 1,2,3,4,5,6,12。
猜你喜欢
  • 1970-01-01
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多