编译器优化:G 比英特尔慢
Compiler optimization: g++ slower than intel
我最近在C 中获取了一台带有双启动的计算机。在Windows上,我在Linux上使用Intel C 编译器和G 。我的程序主要由计算(具有数值集成等的固定点迭代算法等(组成。
我以为我可以在Linux上的Windows附近获得表演,但是到目前为止,我还没有:对于完全相同的代码,使用G 编译的程序比Intel编译器慢了2倍。从我阅读的内容来看,ICC可以更快,甚至可能收益20%至30%,但我没有读到有关它的速度两倍(总的来说,我实际上都读到两者都应该是同等的(。
首先,我使用的是大约等效的标志:
icl/openMP/i" c: boost_1_61_0"/fast Program.cpp
和
g -o program.cpp -std = c 11 -fopenmp -o3 -ffast -Math
遵循其他几个主题的建议,我尝试添加/替换其他几个标志,例如:-funsafe -math -optimizations,-march =本机,-f fhole -few program,-ofast,-ofast等。
ICC真的很快还是我缺少什么?我是Linux的新手,所以我不知道,也许我忘了正确安装某些内容(例如驱动程序(,或者在G 中更改某些选项?我不知道情况是否正常,这就是为什么我更喜欢问。尤其是因为我更喜欢使用Linux来理想地编码,因此我宁愿要尽快加速。
编辑:我决定在Linux上安装最后一个Intel编译器(Intel Compiler C 17,Update4(进行检查。我最终得到了缓解的结果:它的表现并不比GCC更好(实际上更糟糕(。我运行了交叉比较linux/Windows -ICC/GCC-使用帖子前面提到的标志(为了进行直接比较(,这是我的结果( time 运行1次迭代, MS (:
-
普通环,无平行化:
- Windows:
GCC = 122074;ICC = 68799 - linux:
GCC = _91042;ICC = 92102
- Windows:
-
并行版本:
- Windows:
GCC = 27457;ICC = 19800 - linux:
GCC = 27000;ICC = 30000
- Windows:
总结:这有点混乱。在Linux上,GCC似乎总是比ICC更快,尤其是在涉及并行化时(我将其用于更长的程序,差异比这里的差异要高得多(。
在Windows上,情况恰恰相反,ICC显然主导了海湾频道,尤其是在没有并行化的情况下(在这种情况下,GCC需要很长时间才能编译(。
最快的汇编是在Windows上使用并行化和ICC完成的。我不明白为什么我不能在Linux上复制它。我需要做什么(Ubuntu 16.04(来帮助固定我的流程吗?
另一个区别是,在Windows上,我使用旧的英特尔作曲家( Composer Xe 2013 (并调用' ia32 '而不是Intel64(这是我应该使用的(在Linux上,我使用昨天安装的最后一个版本。在Linux上,Intel编译器17文件夹在我的第二个HDD上(而不是我的SSD安装的SSD(,我不知道这是否也可能会减慢速度。
知道问题可能来自哪里吗?
编辑:精确的硬件: Intel(R(Core(TM(I7-4710HQ CPU @ 2.50GHz,8 CPU,4核,每个核心2个线程,体系结构x86_64-Linux ubuntu 16.04带有GCC 5.4.1和Intel编译器17(Update4(-Windows 8.1,英特尔作曲家2013
编辑:代码很长,这是我正在测试的循环的形式(即我的固定点迭代的一个迭代(。我想这是非常经典的...不确定它会带入这个话题。
// 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函数是一种经典而简单的优化算法(自定义 Golden Search (返回最佳值及其参数:
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; }
在计算(从预编译网格中选择一个网格点(row_index((方面,优化功能(intra_value(非常复杂,然后涉及大量的数值集成等(。
看起来您正在使用OpenMP,因此我怀疑差异在OpenMP实现中,而不仅仅是优化代码的质量。
Intel的OpenMP运行时众所周知,GCC很好,但不是很好。
OpenMP程序具有非常不同的性能特征,它们不仅取决于编译器可以如何优化循环或内联函数调用。OpenMP运行时的实现非常重要,并且在Windows和GNU/Linux之间大不相同。
请注意,"快速记忆"打破了某些语言规则以获取快速代码,并在某些情况下可能会产生不正确的结果。
还请注意,-O3
不是保证比-O2
或其他任何优化级别(取决于您的代码( - 您应该测试多个版本。
您可能还需要启用-Wl,-O1
-链接器也可以进行一些优化。
您可能还想尝试使用LTO建造(链接时间优化( - 通常可以取得重大改进。
我意识到这并没有回答您的问题。但这应该给您一些可以玩的东西: - (
此外,海湾合作委员会的进步很快。如果您尚未使用7.1,则可能需要尝试较新的版本。还;尝试clang以获取第三个数据点。此外,您 can (如果需要(在Linux上使用ICC。
- 编译要在英特尔Hyperscan中使用的.cc文件时出现问题
- 将gsl c++程序与"英特尔MKL"链接
- 使用英特尔 PIN 修改寄存器
- 使用英特尔内联函数将打包的 8 位整数乘以浮点数向量
- 如何使用英特尔 PIN 捕获阵列的所有负载?
- 英特尔 TBB 程序不会终止,可能会误用参考计数器
- 将"-01"替换为"-02" 英特尔编译器选项会导致 FPE 在较小的 for 循环行程计数中抛出
- 在 Azure DevOps 构建管道中使用英特尔C++编译器为 Linux 环境构建C++代码
- 编译器错误(英特尔并行工作室 2019 与 Visual Studio 社区 2019)
- 如何要求 macports 用英特尔编译器包装 openmpi?
- 实施英特尔实感和 SDL2 时出现问题
- OpenGL 片段着色器未在英特尔 HD 4000 显卡上编译
- 英特尔将指令存储在重叠的内存区域
- 如何指示 CMAKE 在 Visual Studio 中使用英特尔 MKL
- 使用英特尔内部函数 (AVX) 中的混合说明
- 编译器优化:G 比英特尔慢
- 英特尔顾问优化标志和设置
- 英特尔Sandybridge系列CPU中管道程序的去优化
- C++英特尔TBB内部循环优化
- 防止英特尔编译器过度优化未使用的变量