热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

编译器优化:g++比intel慢

如何解决《编译器优化:g++比intel慢》经验,为你挑选了2个好方法。

我最近购买了一台带有双启动的计算机,用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 program.cpp -std = c ++ 11 -fopenmp -O3 -ffast-math

根据其他几个主题的建议,我尝试添加/替换其他几个标志,如: - funsafe-math-optimizations,-march = native,-fwhole-program,-Ofast等,只有轻微(或没有)性能增益.

icc真的更快还是我错过了什么? 我对linux很新,所以我不知道,也许我忘了安装正确的东西(比如驱动程序),或者用g ++改变一些选项?我不知道情况是否正常,这就是我更喜欢问的原因.特别是因为我更喜欢使用linux进行理想的编码,所以我宁愿让它达到速度.

编辑:我决定在linux上安装最后一个intel编译器(Intel Compiler C++ 17,update4)来检查.我最终得到了缓解的结果:它并不比gcc做得更好(事实上甚至更糟).我运行交叉比较linux/windows - icc/gcc - 并行或不使用,使用前面提到的标志(进行直接比较),这是我的结果(以ms为单位运行1次迭代的时间):

    普通循环,没有并行化:

    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,特别是当没有并行化时(在这种情况下gcc需要很长时间才能编译).

最快的编译是通过Windows上的并行化和icc完成的.我不明白为什么我不能在linux上复制这个.有什么我需要做的(ubuntu 16.04)来帮助加固我的流程吗?
另一个区别是在Windows上我使用较旧的英特尔作曲家(Composer XE 2013)并调用' ia32 '而不是intel64(我应该使用的那个),而在linux上我使用我昨天安装的最后一个版本.在Linux上,英特尔编译器17文件夹在我的第二个硬盘上(而不是我安装Linux的ssd)我不知道这是否会减慢速度.
知道问题可能来自哪里?

编辑:精确硬件:Intel(R)Core(TM)i7-4710HQ CPU @ 2.50GHz,8个CPU,4个内核,每个内核2个线程,架构x86_64 - 带有gcc 5.4.1的Linux Ubuntu 16.04和Intel编译器17(update4) - Windows 8.1,Intel Composer 2013

编辑:代码很长,这是我正在测试的循环形式(即我的定点迭代的一次迭代).这是非常经典的我猜...不确定它能为这个话题带来什么.

// initialization of all the objects...
// length_grid1 is about 2000
vector 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 

其中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),然后涉及大量数值积分等).



1> Jonathan Wak..:

看起来您正在使用OpenMP,因此我怀疑OpenMP实现中的差异,而不仅仅是优化代码的质量.

众所周知,英特尔的OpenMP运行时性能非常高,而且GCC很好,但不是很好.

OpenMP程序具有非常不同的性能特征,它们不仅取决于编译器优化循环或内联函数调用的程度.OpenMP运行时的实现很重要,以及线程和同步原语的操作系统实现,这在Windows和GNU/Linux之间是完全不同的.



2> Jesper Juhl..:

请注意,"fast-math"会破坏某些语言规则以获取快速代码,并且在某些情况下可能会产生不正确的结果.

另请注意,-O3不能保证-O2其他优化级别更快(取决于您的代码) - 您应该测试多个版本.

您可能还想启用-Wl,-O1- 链接器也可以进行一些优化.

您可能还想尝试使用LTO构建(链接时间优化) - 它通常可以产生显着的改进.

我意识到这不能回答你的问题.但它应该给你一些东西:-)

此外,gcc正在快速提升.如果您尚未使用7.1,则可能需要尝试更新的版本.也; 尝试Clang获得第三个数据点.此外,如果您愿意,可以在Linux上使用icc.


推荐阅读
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 【技术分享】一个 ELF 蠕虫分析
    【技术分享】一个 ELF 蠕虫分析 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文记录了作者对x265开源代码的实现与框架进行学习与探索的过程,包括x265的下载地址与参考资料,以及在Win7 32 bit PC、VS2010平台上的安装与配置步骤。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 通过Anaconda安装tensorflow,并安装运行spyder编译器的完整教程
    本文提供了一个完整的教程,介绍了如何通过Anaconda安装tensorflow,并安装运行spyder编译器。文章详细介绍了安装Anaconda、创建tensorflow环境、安装GPU版本tensorflow、安装和运行Spyder编译器以及安装OpenCV等步骤。该教程适用于Windows 8操作系统,并提供了相关的网址供参考。通过本教程,读者可以轻松地安装和配置tensorflow环境,以及运行spyder编译器进行开发。 ... [详细]
  • PeopleSoft安装镜像版本及导入语言包的方法
    本文介绍了PeopleSoft安装镜像的两个版本,分别是VirtualBox虚拟机版本和NativeOS版本,并详细说明了导入语言包的方法。对于Windows版本,可以通过psdmt.exe登录进入,并使用datamover脚本导入语言包。对于Linux版本,同样可以使用命令行方式执行datamover脚本导入语言包。导入语言包后,可以实现多种语言的登录。参考文献提供了相关链接以供深入了解。 ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
  • 目录1、将mysql数据导出到SQL文件中(数据库存在的情况)2、将现有的sql文件数据导入到数据库中(前提数据库存在) 3、利用Navicat导出SQL文件和导入SQL文件1)从 ... [详细]
  • 第四讲ApacheLAMP服务器基本配置Apache的编译安装从Apache的官方网站下载源码包:http:httpd.apache.orgdownload.cgi今 ... [详细]
  • 原文地址http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/最开始时 ... [详细]
  • centos6.8 下nginx1.10 安装 ... [详细]
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
author-avatar
老翅几回寒_332
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有