请查看此代码。
单线程程序: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
我不明白出了什么问题。
答案 0 :(得分:2)
您的目标是研究OpenMP,还是让您的计划更快?如果是后者,那么编写乘法 - 加法代码,减少传递次数以及合并SIMD将更有价值。
步骤1:组合循环并使用multiply-add:
// 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);
}
答案 1 :(得分:2)
使用-static和-p进行编译,运行然后使用gprof解析gmon.out:
45.65%gomp_barrier_wait_end
这是在opemmp的障碍例程中花了很多时间。这是等待其他线程完成所花费的时间。因为你多次运行并行for循环(LAYERS),所以你失去了并行运行的优势,因为每次并行for循环结束时,都会有一个隐式屏障调用,在所有其他线程完成之前不会返回。
答案 2 :(得分:0)
在其他任何事情之前,在多线程配置上运行测试并确保procexp或任务管理器将显示100%的CPU使用率。如果没有,那么您不使用多个线程也不使用多个处理器核心。
另外,取自维基:
环境变量
一种改变OpenMP应用程序执行功能的方法。用于控制循环迭代调度,默认线程数等。例如,OMP_NUM_THREADS用于指定应用程序的线程数。
答案 3 :(得分:0)
我没看到你实际使用OpenMP的位置 - 在主循环上方尝试#pragma omp parallel ...(例如documented here)
缓慢可能来自包括OpenMP和初始化,添加代码膨胀或以其他方式更改编译,因为您引入的编译器标志启用它。或者,循环非常小且简单,以至于线程开销远远超过性能增益。