C++ 动态链接时英特尔PARDISO分解速度较慢

C++ 动态链接时英特尔PARDISO分解速度较慢,c++,linux,intel-mkl,C++,Linux,Intel Mkl,我们有一个运行PARDISO解算器的代码。当我们静态链接这段代码时,分解步骤比静态链接同一段代码时快2倍 以下是在这两种情况下从CMake获得的链接线(我使用了MKL链接线顾问来帮助我定义参数): 静态链接: /opt/intel/compilers_and_libraries_2016/linux/bin/intel64/icpc -rdynamic CMakeFiles/simplesolver.dir/pardiso_sym_c.cpp.o -o simplesolver -Wl,

我们有一个运行PARDISO解算器的代码。当我们静态链接这段代码时,分解步骤比静态链接同一段代码时快2倍

以下是在这两种情况下从CMake获得的链接线(我使用了MKL链接线顾问来帮助我定义参数):

静态链接:

/opt/intel/compilers_and_libraries_2016/linux/bin/intel64/icpc    -rdynamic CMakeFiles/simplesolver.dir/pardiso_sym_c.cpp.o  -o simplesolver -Wl,--start-group /opt/intel/compilers_and_libraries_2016/linux/mkl/lib/intel64/libmkl_intel_lp64.a /opt/intel/compilers_and_libraries_2016/linux/mkl/lib/intel64/libmkl_intel_thread.a /opt/intel/compilers_and_libraries_2016/linux/mkl/lib/intel64/libmkl_core.a -Wl,--end-group -liomp5 -lpthread -lm -ldl 
/opt/intel/compilers_and_libraries_2016/linux/bin/intel64/icpc   
-rdynamic CMakeFiles/simplesolver.dir/pardiso_sym_c.cpp.o  -o simplesolver
-L/opt/intel/compilers_and_libraries_2016/linux/mkl/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -ldl
动态链接:

/opt/intel/compilers_and_libraries_2016/linux/bin/intel64/icpc    -rdynamic CMakeFiles/simplesolver.dir/pardiso_sym_c.cpp.o  -o simplesolver -Wl,--start-group /opt/intel/compilers_and_libraries_2016/linux/mkl/lib/intel64/libmkl_intel_lp64.a /opt/intel/compilers_and_libraries_2016/linux/mkl/lib/intel64/libmkl_intel_thread.a /opt/intel/compilers_and_libraries_2016/linux/mkl/lib/intel64/libmkl_core.a -Wl,--end-group -liomp5 -lpthread -lm -ldl 
/opt/intel/compilers_and_libraries_2016/linux/bin/intel64/icpc   
-rdynamic CMakeFiles/simplesolver.dir/pardiso_sym_c.cpp.o  -o simplesolver
-L/opt/intel/compilers_and_libraries_2016/linux/mkl/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -ldl
这有什么已知的问题吗?或者我们缺少一些编译/链接标志来提高因子分解性能?代码完全相同(来自MKL发行版的solverc示例)。我们唯一改变的是如何连接,然后我们得到了运行速度的巨大差异

我们使用英特尔编译器C++ 2016,使用Linux下的MKL(Ubuntu 14.04)。我们通过查看PARDISO的输出(msglvl=1)来测量时间

只有在有帮助的情况下,这才是代码(我使用函数readData从文件中读取矩阵信息)

#包括“mkl_pardiso.h”
#包括“mkl_类型.h”
#包括
#包括
#包括
#包括
#包括
MKL_内部干管(无效)
{
int n;//矩阵的维数
int nnz;//非零的数目
int*ia;//a中每个值在i中的坐标
int*ja;//a中每个值的坐标,单位为j
double*a;//矩阵的值
double*b;//力向量
double*x_预期;//计算解决方案我们的软件(Ax=rhs)
double*x;//pardiso中的计算解
布尔结果=假;
std::string fileIn=“problemData.bin”;
//方法填充所有值…不相关。
结果=读取数据(预期为fileIn、n、nnz、ia、ja、a、b和x_、false);
x=新的双精度[n];
如果(!结果)
返回1;
MKL_INT mtype=-2;/*实对称矩阵*/
/*RHS和解向量*/
MKL_INT nrhs=1;/*右侧的数量*/
/*内部解算器内存指针pt*/
/*32位:int-pt[64];64位:长int-pt[64]*/
/*或者void*pt[64]在两种体系结构上都应该可以*/
void*pt[64];
/*Pardiso控制参数*/
MKL_INT iparm[64];
MKL_INT maxfct,mnum,相位,误差,msglvl;
/*辅助变量*/
MKL_INT i;
双ddum;/*双虚拟*/
MKL_INT idum;/*整数伪*/
/* -------------------------------------------------------------------- */
/*..设置ISO控制参数*/
/* -------------------------------------------------------------------- */
对于(i=0;i<64;i++)
{
iparm[i]=0;
}
iparm[0]=1;/*无解算器默认值*/
iparm[1]=2;/*填写从METIS重新订购*/
iparm[3]=0;/*无迭代直接算法*/
iparm[4]=0;/*没有用户填写减少排列*/
iparm[5]=0;/*将解决方案写入x*/
iparm[6]=0;/*未使用*/
iparm[7]=2;/*迭代优化步骤的最大数量*/
iparm[8]=0;/*未使用*/
iparm[9]=13;/*使用1E-13扰动枢轴元素*/
iparm[10]=1;/*使用非对称排列和缩放MPS*/
iparm[11]=0;/*未使用*/
iparm[12]=0;/*最大加权匹配算法已关闭(对称的默认值)。如果精度不合适,请尝试iparm[12]=1*/
iparm[13]=0;/*输出:受扰动的枢轴数*/
iparm[14]=0;/*未使用*/
iparm[15]=0;/*未使用*/
iparm[16]=0;/*未使用*/
iparm[17]=-1;/*输出:因子LU中的非零数*/
iparm[18]=-1;/*输出:用于LU因式分解的MFLOP*/
iparm[19]=0;/*输出:CG迭代次数*/
maxfct=1;/*数值因式分解的最大数目*/
mnum=1;/*要使用的因式分解*/
msglvl=1;/*在文件中打印统计信息*/
错误=0;/*初始化错误标志*/
/* -------------------------------------------------------------------- */
/*..初始化内部解算器内存指针。这只是*/
/*第一次调用PARDISO解算器所必需的*/
/* -------------------------------------------------------------------- */
对于(i=0;i<64;i++)
{
pt[i]=0;
}
/* -------------------------------------------------------------------- */
/*…重新排序和符号分解。此步骤还分配*/
/*分解所需的所有内存*/
/* -------------------------------------------------------------------- */
相位=11;
PARDISO(pt、maxfct、mnum、mtype和phase、,
&n、 a、ia、ja、idum、nrhs、iparm、msglvl、ddum、ddum和错误);
如果(错误!=0)
{
printf(“\n符号因式分解期间出错:%d”,错误);
返回-1;
}
printf(“\n订购完成…”);
printf(“\n因子中非零的数目=%d”,iparm[17]);
printf(“\n因子分解MFLOPS的数目=%d”,iparm[18]);
/* -------------------------------------------------------------------- */
/*…数值因式分解*/
/* -------------------------------------------------------------------- */
相位=22;
PARDISO(pt、maxfct、mnum、mtype和phase、,
&n、 a、ia、ja、idum、nrhs、iparm、msglvl、ddum、ddum和错误);
如果(错误!=0)
{
printf(“\n数字因式分解期间出错:%d”,错误);
返回-2;
}
printf(“\n工厂化完成…”);
/* -------------------------------------------------------------------- */
/*…回代和迭代求精*/
/* -------------------------------------------------------------------- */
相位=33;
iparm[7]=2;/*迭代优化步骤的最大数量*/
PARDISO(pt、maxfct、mnum、mtype和phase、,