Visual studio 2017 在Visual Studio 2017中启用开放式MP支持会降低代码的速度
我正在尝试使用OpenMP来加速我的神经网络计算代码。由于我正在使用Visual Studio 2017,我需要在属性页中启用OpenMP支持。但是,在我这样做之后,代码的某些部分会减慢大约5倍,即使我没有在代码中包含任何Visual studio 2017 在Visual Studio 2017中启用开放式MP支持会降低代码的速度,visual-studio-2017,openmp,eigen,Visual Studio 2017,Openmp,Eigen,我正在尝试使用OpenMP来加速我的神经网络计算代码。由于我正在使用Visual Studio 2017,我需要在属性页中启用OpenMP支持。但是,在我这样做之后,代码的某些部分会减慢大约5倍,即使我没有在代码中包含任何#pragma omp 我已经隔离了这些部分,并发现这一特定功能导致了问题: void foo(Eigen::Matrix<float,3,Eigen::Dynamic> inputPts) { std::vector<Eigen::MatrixXf&
#pragma omp
我已经隔离了这些部分,并发现这一特定功能导致了问题:
void foo(Eigen::Matrix<float,3,Eigen::Dynamic> inputPts)
{
std::vector<Eigen::MatrixXf> activation;
activation.reserve(layerNo);
activation.push_back(inputPts);
int inputNo = inputPts.cols();
for (int i = 0; i < layerNo - 2; i++)
activation.push_back(((weights[i]*activation[i]).colwise()+bias[i]).array().tanh());
activation.push_back(((weights[layerNo - 2]*activation[layerNo - 2]).colwise()+bias[layerNo - 2]));
val = activation[layerNo - 1]/scalingFactor;
std::vector<Eigen::MatrixXf> delta;
delta.reserve(layerNo);
Eigen::Matrix<float, 1, Eigen::Dynamic> seed;
seed.setOnes(1, inputNo);
delta.push_back(seed);
for (int i = layerNo - 2; i >= 1; i--)
{
Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic>
d_temp = weights[i].transpose()*delta[layerNo - 2 - i],
d_temp2 = 1 - activation[i].array().square(),
deltaLayer = d_temp.cwiseProduct(d_temp2);
delta.push_back(deltaLayer);
}
grad = weights[0].transpose()*delta[layerNo - 2];
}
void foo(特征::矩阵输入)
{
载体激活;
激活。保留(layerNo);
激活。推回(输入点);
int inputNo=inputps.cols();
对于(int i=0;i=1;i--)
{
本征矩阵
d_temp=weights[i].transpose()*delta[layerNo-2-i],
d_temp2=1-激活[i].array().square(),
deltaLayer=d_temp.cwiseProduct(d_temp2);
delta.推回(deltaLayer);
}
梯度=权重[0]。转置()*delta[layerNo-2];
}
两个for环路的速度显著降低(从~3ms到~20ms)。奇怪的是,虽然这个函数在程序中被多次调用,但只有其中一些函数受到影响
我已经包含了头文件
。我不确定这是否是由于到处都使用的特征库。我尝试定义EIGEN\u DONT\u PARALLELIZE
并按照中的建议调用EIGEN::initParallel()
,但没有任何帮助
奇怪的是,我甚至没有包含任何
并行pragma
,处理OpenMP函数不应该有任何开销?为什么它仍在减速?如果启用OpenMP,默认情况下,Eigen的矩阵产品是多线程的。问题可能是以下因素的组合:
Eigen\u DONT\u PARALLELIZE
来禁用Eigen的多线程
更多信息请访问
有关超线程如何降低性能的更多详细信息:
使用“超线程”,您可以在一个内核上以交错方式运行两个线程。他们轮流执行每项指令。如果您的线程使用的CPU资源(在计算方面)不少于一半,那么这是一个胜利,因为您将利用更多的计算单元。但是,如果单个线程已经使用了100%的计算单元(如优化良好的矩阵积),那么您将失去性能,因为1)管理两个线程的自然开销,2)因为一级缓存现在由两个不同的任务共享。矩阵核的设计考虑了精确的L1容量。使用两个线程,一级缓存几乎变得无效。这意味着,在大多数情况下,不是获取非常快的一级缓存,而是访问速度慢得多的二级缓存,从而导致性能大幅下降。与Linux和Windows不同,在OSX上,我没有观察到这样的性能下降,很可能是因为如果CPU已经太忙,系统能够取消第二个线程的调度。谢谢您的回复。我添加了行
omp\u set\u num\u线程(2);特征::setNbThreads(1);Eigen::initParallel()代码>(请参阅),运行时将恢复正常。不幸的是,即使我添加了#pragma
语句,我的计时也没有改进。在我的例子中,并行线程是不够的。只需要澄清一下:超线程是如何导致这个问题的?将OMP_NUM_THREADS设置为2会提供通常的运行时间,但4会降低代码的速度。这就是我在回答中试图解释的,我用更多细节扩展了回答。