我最近买了一台双系统电脑来编写C ++代码。在Windows上,我使用Intel C ++编译器,在Linux上使用g++。我的程序主要由计算组成(带有数值积分的定点迭代算法等)。我认为我可以在Linux上获得接近Windows的性能,但目前还没有:对于完全相同的代码,使用g ++编译的程序比使用Intel编译器的程序慢约2倍。从我所读的内容来看,icc可能会更快,甚至可以获得20-30%的收益,但我没有读到任何关于它比g ++快两倍(通常情况下,我确实读到它们应该是相等的)的信息。
最初,我使用的标志大致相等:
icl /openmp /I "C:\boost_1_61_0" /fast program.cpp 和
g ++ -o program program.cpp -std = c ++ 11 -fopenmp -O3 -ffast-math
根据几个其他主题的建议,我尝试添加/替换了几个其他标志,例如:-funsafe-math-optimizations,-march = native,-fwhole-program,-Ofast等,但只有轻微(或没有)性能提升。
icc真的更快吗?还是我漏掉了什么?我对Linux还比较新,因此我不知道,也许我忘记正确安装某些内容(例如驱动程序)或更改g ++中的某些选项?我不知道情况是否正常,这就是为什么我宁愿问。特别是因为我理想地想要使用Linux进行编码,因此我宁愿让它达到速度。
编辑:我决定在Linux上安装最后一个英特尔编译器(Intel Compiler C ++ 17,update4)进行检查。 我得到了暂时的结果:它并没有比gcc做得更好(实际上更糟)。我使用本文中提到的标志(以进行直接比较)运行了交叉对比linux / windows-icc / gcc-并行化与否,以下是我的结果(测量1次迭代运行时间以ms为单位):
纯循环,无并行化:
Windows:
gcc = 122074 ; icc = 68799
Linux:
gcc = _91042; icc = 92102 并行化版本:
Windows:
gcc = 27457; icc = 19800
Linux:
gcc = 27000; icc = 30000
总而言之:有点混乱。 在Linux上,gcc似乎总是比icc快,特别是当涉及并行化时(我运行了较长的程序,差异要大得多)。在Windows上,情况相反,icc显然占优势,特别是在没有并行化的情况下(在这种情况下,gcc需要很长时间进行编译)。
最快的编译是使用并行化和icc在Windows上完成的。我不明白为什么我无法在Linux上复制此操作。是否有任何我需要执行的操作(ubuntu 16.04)来加速我的进程?另一个区别是,在Windows上,我使用较旧的英特尔作曲家(Composer XE 2013),并调用“ia32”而不是intel64(我应该使用的那个),而在Linux上,我使用了昨天安装的最新版本。在Linux上,Intel Compiler 17文件夹位于我的第二个硬盘驱动器上(而不是安装Linux的SSD上),我不知道这也可能减慢速度。问题可能来自哪里?
编辑:确切的硬件: Intel(
最初,我使用的标志大致相等:
icl /openmp /I "C:\boost_1_61_0" /fast program.cpp 和
g ++ -o program program.cpp -std = c ++ 11 -fopenmp -O3 -ffast-math
根据几个其他主题的建议,我尝试添加/替换了几个其他标志,例如:-funsafe-math-optimizations,-march = native,-fwhole-program,-Ofast等,但只有轻微(或没有)性能提升。
icc真的更快吗?还是我漏掉了什么?我对Linux还比较新,因此我不知道,也许我忘记正确安装某些内容(例如驱动程序)或更改g ++中的某些选项?我不知道情况是否正常,这就是为什么我宁愿问。特别是因为我理想地想要使用Linux进行编码,因此我宁愿让它达到速度。
编辑:我决定在Linux上安装最后一个英特尔编译器(Intel Compiler C ++ 17,update4)进行检查。 我得到了暂时的结果:它并没有比gcc做得更好(实际上更糟)。我使用本文中提到的标志(以进行直接比较)运行了交叉对比linux / windows-icc / gcc-并行化与否,以下是我的结果(测量1次迭代运行时间以ms为单位):
纯循环,无并行化:
Windows:
gcc = 122074 ; icc = 68799
Linux:
gcc = _91042; icc = 92102 并行化版本:
Windows:
gcc = 27457; icc = 19800
Linux:
gcc = 27000; icc = 30000
总而言之:有点混乱。 在Linux上,gcc似乎总是比icc快,特别是当涉及并行化时(我运行了较长的程序,差异要大得多)。在Windows上,情况相反,icc显然占优势,特别是在没有并行化的情况下(在这种情况下,gcc需要很长时间进行编译)。
最快的编译是使用并行化和icc在Windows上完成的。我不明白为什么我无法在Linux上复制此操作。是否有任何我需要执行的操作(ubuntu 16.04)来加速我的进程?另一个区别是,在Windows上,我使用较旧的英特尔作曲家(Composer XE 2013),并调用“ia32”而不是intel64(我应该使用的那个),而在Linux上,我使用了昨天安装的最新版本。在Linux上,Intel Compiler 17文件夹位于我的第二个硬盘驱动器上(而不是安装Linux的SSD上),我不知道这也可能减慢速度。问题可能来自哪里?
编辑:确切的硬件: Intel(
// initialization of all the objects...
// length_grid1 is about 2000
vector< double > V_NEXT(length_grid1), PRICE_NEXT(length_grid1);
double V_min, price_min;
#pragma omp parallel
{
#pragma omp for private(V_min, price_min, i, indexcurrent, alpha, beta)
for (i = 0; i < length_grid1; i++) {
indexcurrent = indexsum[i];
V_min = V_compute(&price_min, indexcurrent, ...);
V_NEXT[indexcurrent] = V_min; PRICE_NEXT[indexcurrent] = price_min;
}
}// end parallel
V_compute函数是一个经典而简单的优化算法(自定义的黄金分割),它返回最优值及其参数:
double V_compute(double *xmin, int row_index, ... ) {
double x1, x2, f1, f2, fxmin;
// golden_ratio=0.61803399;
x1 = upper_bound - golden_ratio*(upper_bound - lower_bound);
x2 = lower_bound + golden_ratio*(upper_bound - lower_bound);
// Evaluate the function at the test points
f1 = intra_value(x1, row_index, ...);
f2 = intra_value(x2, row_index, ...);
while (fabs(upper_bound - lower_bound) > tolerance) {
if (f2 > f1){
upper_bound = x2; x2 = x1; f2 = f1;
x1 = upper_bound - golden_ratio*(upper_bound - lower_bound);
f1 = intra_value(x1, row_index, ...);
} else {
lower_bound = x1; x1 = x2; f1 = f2;
x2 = lower_bound + golden_ratio*(upper_bound - lower_bound);
f2 = intra_value(x2, row_index, ...);
}
}
// Estimated minimizer = (lower bound + upper bound) / 2
*xmin = (lower_bound + upper_bound)/2;
fxmin = intra_value(*xmin, row_index, ...);
return - fxmin; }
在计算方面,被优化的函数 (intra_value) 相当复杂 (从预编译的网格中选择一个网格点 (row_index),然后涉及大量的数值积分等)。