4

请看这段代码。

单线程程序: http: //pastebin.com/KAx4RmSJ。编译:

g++ -lrt -O2 main.cpp -o nnlv2

多线程与 openMP:http ://pastebin.com/fbe4gZSn 编译:

g++ -lrt -fopenmp -O2 main_openmp.cpp -o nnlv2_openmp

我在双核系统上对其进行了测试(所以我们有两个并行运行的线程)。但是多线程版本比单线程版本慢(并且显示不稳定的时间,请尝试运行几次)。怎么了?我在哪里犯错了?

一些测试:

单线程:

Layers Neurons Inputs --- Time (ns)

10 200 200 --- 1898983

10 500 500 --- 11009094

10 1000 1000 --- 48116913

多线程:

Layers Neurons Inputs --- Time (ns)

10 200 200 --- 2518262

10 500 500 --- 13861504

10 1000 1000 --- 53446849

我不明白出了什么问题。

4

4 回答 4

2

您的目标是学习 OpenMP,还是让您的程序更快?如果是后者,则更值得编写乘加代码、减少传递次数并合并 SIMD。

第 1 步:组合循环并使用乘加:

// remove the variable 'temp' completely
for(int i=0;i<LAYERS;i++)
{
  for(int j=0;j<NEURONS;j++)
  {
    outputs[j] = 0;

    for(int k=0,l=0;l<INPUTS;l++,k++)
    {
      outputs[j] += inputs[l] * weights[i][k];
    }

    outputs[j] = sigmoid(outputs[j]);
  }

  std::swap(inputs, outputs);
}
于 2011-07-13T00:27:15.780 回答
2

用 -static 和 -p 编译,运行然后用 gprof 解析 gmon.out 我得到:

45.65% gomp_barrier_wait_end

在 opemmp 的屏障程序中,这是很长的时间。这是等待其他线程完成所花费的时间。由于您多次运行并行 for 循环(层),因此您失去了并行运行的优势,因为每次并行 for 循环完成时,都会有一个隐式屏障调用,直到所有其他线程完成后才会返回。

于 2011-07-20T04:43:37.887 回答
0

首先,在多线程配置上运行测试,并确保 procexp 或任务管理器将显示 100% 的 CPU 使用率。如果没有,那么您就不会使用多个线程或多个处理器内核。

另外,取自维基:

环境变量

一种更改 OpenMP 应用程序执行功能的方法。用于控制循环迭代调度、默认线程数等。例如OMP_NUM_THREADS用于指定应用程序的线程数。

于 2011-07-12T23:57:28.333 回答
0

我没有看到您在哪里实际使用过 OpenMP - 在主循环上方尝试 #pragma omp parallel ...(例如,在此处记录)

缓慢可能是由于包含 OpenMP 及其初始化、添加代码膨胀或以其他方式更改编译,因为您引入了启用它的编译器标志。或者,循环是如此的小和简单,以至于线程的开销远远超过了性能增益。

于 2011-07-13T01:41:40.837 回答