intel编译器_基于Intel编译器的优化(持续学习消化)

基于Intel编译器的优化

编译器优化级别

Intel的编译器共有如下一些主要的优化级别:

  • u /O1:实现最基本的优化
  • u /O2:基于代码速度实现常规优化,这个也是默认的优化级别
  • u /O3:在/O2的基础上实现进一步的优化,包括Cache预读,标量转换等等,但是在某些情况下反而会减慢代码的执行速度。
  • u /Ox:实现最大化的优化,包括自动内联函数的确定,全局优化,使用EBP作为通用寄存器等。
  • u /fast:等同于/O3, /Qipo, /Qprec-div-, and /QxP。

随着代码的更改,需要重新测试,选择合适的优化级别。

针对特定处理器进行优化

Intel的编译器一共支持如下3种针对特定处理器的优化:

  • u /G:使用这个优化选项,Intel将针对特定的CPU进行优化,但是其代码依然可以在所有的CPU上执行。
  • u /Qx:使用这个优化选项,Intel将针对特定的CPU进行优化,并且产生的代码无法使用在不兼容的CPU上。
  • u /Qax:使用这个优化选项,Intel将针对特定的CPU进行优化,并且产生多份代码,在运行时根据CPU类型自动选择最优的代码。

使用IPO

使用/Q ipo可以启用Intel编译器的过程间优化(Interprocedural Optimizations)。通过过程间优化,编译器可以通过使用寄存器优化函数调用、内联函数展开、过程间常数传递、跨多文件优化等方式进一步优化程序。

但是IPO优化却会对本程序的调试带来极大的麻烦。所以本程序开发时不使用IPO优化,只有在最后的版本中才尝试使用IPO优化能否提高效率。

使用GPO

Intel编译器支持GPO(Profile-Guided Optimization)。GPO由三步组成。

  • 第一步:使用/Q prof-gen编译程序,产生能记录运行细节的特殊程序。
  • 第二步:运行第一步产生的程序,生成动态信息文件(.dyn)。
  • 第三步,使用/Q prof-use,结合动态信息文件重新编译程序,产生更优化的程序。

通过使用GPO,Intel编译器可以更详细得了解程序的运行情况,从而根据实际情况产生更优化的代码。比如优化条件跳转,使得CPU分支预测的能力更准确,又如决定哪些函数需要内联,哪些不要内联等。

此外,基于GPO还有很多的工具方便用户开发程序。比如Code-Coverage Tool可以进行代码覆盖测试。

由于GPO收集的信息和特定的程序有关,而本程序一直在修改。所以本程序只在每个版本的最后部分使用GPO进行优化。

循环展开

循环展开(Loop Unrolling)通过在把循环语句中的内容展开从而使执行的代码速度更快。循环展开可以提高代码的并行程度,减少条件转移次数从而提高速度。另外,对于Pentium 4处理器,其分支预测功能可以精确得预测出16次迭代以内的循环,所以,如果能把循环展开到迭代次数在16次以内,对于特定的CPU可以提高分支预测准确度。

但是循环展开必须有一个度,并不是展开层数越多越好,展开层数多了,可能反而影响代码的执行速度。所以通常的做法是让编译器自己决定循环展开的层数。

Intel编译器对于循环展开有如下选项:

  • u /Qunrolln:执行循环展开n层。
  • u /Qunroll:让Intel编译器自己决定循环展开的层数。

此外Intel编译器还提供在了程序中使用编译制导语句规定某个特定循环的展开次数。如下例指示for循环展开n层。

#pragma unroll(n)
for(i=0;i<10000;i++){……}

建议程序使用/Q unroll参数,让Intel编译器自己决定使用循环展开的层数。但是在程序的最终优化时,如果发现Intel编译器的循环展开并不是最优的,则通过在特定循环前加上编译制导语句,使用最佳的循环展开层数。

浮点计算优化

Intel编译器提供了很多基于浮点数的优化参数,有提供精度的,也有提高速度的。对于本程序,主要使用如下优化参数。

  • u /fp: fast或/fp: fast=1:这两个参数的等价的,同时也是默认的参数。他告诉编译器进行快速浮点计算优化。
  • u /fp: fast=2:这个参数比/fp: fast=1提供更高的优化级别,同时也可能带来更大的精度损失。

本程序使用/fp: fast=2优化,但是如果发生精度问题,可以考虑使用/fp: fast=1。

自动并行化

Intel的编译器支持自动并行化(Auto-parallelization)。通过/Q parallel可以打开编译器的自动并行化,编译器会在分析了用户的串行程序后,自动选择可以并行的部分进行并行化。自动并行化的有点是方便,不需要用户懂得专业知识,不需要更改原来的串行程序。但是缺点也是显而易见的,由于编译器并不知道用户的程序逻辑,所以无法很好得进行并行化。在对本程序试用/Q parallel后发现,效果并不好。所以本程序不只用/Qparallel进行自动并行化。

使用OpenMP并行化

OpenMP是一种通用的并行程序设计语言,其通过在源代码中添加编译制导语句,提示编译器如何进行程序的并行化。OpenMP具有书写方便,不需要改变源代码结构等多种优点。Intel的编译器支持OpenMP。本次程序并不打算使用OpenMP进行并行化,而打算使用Windows Thread。但是由于本程序需要使用到Intel Math Kernel Library,而Intel Math Kernel Library中的代码支持OpenMP并行化。所以有必要使用一些基本的OpenMP设置函数。

需要使用OpenMP,需要在编译时加上/Q openmp选项。并且在源代码中包含” omp.h”文件。

OpenMP提供了函数omp_set_num_threads(nthreads)设置OpenMP使用的线程数,由于其设置会影响到Intel Math Kernel Library,所以将其设置成1,禁止Intel Math Kernel Library的自动并行化。

向量化

Intel的编译器支持向量化(Vectorization)。可以把循环计算部分使用MMX,SSE,SSE2,SSE3,SSSE3等指令进行向量化,从而大大提高计算速度。这也是本程序串行化时的主要优化点。前面提到的针对处理器的/QaxT优化选项已经打开了向量化。将代码向量化还有许多需要注意的地方,具体的注意点和方法将在后面具体的代码中说明。这里先给出一些对向量化有用的编译制导语句以及选项。

u /Qrestrict选项:当Intel编译器遇到循环中使用指针时,由于多个指针可能指向同一个地址,所以其无法保证指针指向内容的唯一性。故Intel编译器无法确定循环内数据是否存在依赖性。这是可以通过使用/Qrestrict选项与restrict关键字,指示某个指针指向内容的唯一性。从而能解决数据依赖性不确定的问题。

#pragma vector编译制导语句:该编译制导语句一共包含3个。

  • #pragma vector always用于指示编译器忽略其他因素,进行向量化。
  • #pragma vector aligned用于指示编译器进行向量化时使用对齐的数据读写方式。
  • #pragma vector unaligned用于指示编译器进行向量化时使用不对齐的数据读写方式。

由于在使用SSE类指令进行向量化时,需要同时处理多个数据,所以每次读写的数据长度很长,可以达到128bit。所以将要处理的数据按照128bit(16byte)对齐,使用对齐的读写指令是可以提高程序运行速度的。但是需要注意的是对于实际没有对齐的数据使用#pragma vector aligned会造成程序运行错误。

使用变量对齐指示

Intel编译器提供了__declspec(align(n))用于在定义变量时指定其需要进行n字节对齐。变量对齐对于向量化计算的读取速度有很大关系。对于向量化计算一般使用__declspec(align(16))进行对齐。另外也可以使用__declspec(align(64))指定变量对齐到Cache的行首。关于Cache的行对齐的详细讨论请见后文的分析。

数据预读

通常数据是放在内存中,当要计算时才读入CPU进行计算。由于内存到CPU的传输需要很长时间,所以CPU中有多级Cache机制。Intel编译器支持数据预读优化选项。通过/Qprefetch打开数据预读优化,编译器会在使用数据前先插入预读指令,让CPU先把数据预读到Cache中,从而加快数据的访问速度。该选项默认情况下是打开的。

此外Intel还提供了数据预读的编译制导语句,通过使用#pragma prefetch语句,用户可以人为得在程序中增加数据预读指令。

但是需要注意的是,数据预读指令并不是越多越好的。不恰当的数据预读指令会占用内存带宽,把有用的数据从Cache中挤出去,反而影响速度。并且Core Microarchitecture体系结构已经支持给予硬件的数据预读指令。所以本程序倾向于使用给予硬件的数据预读机制。而由于/Qprefetch默认的打开的,也没有必要特意关闭该选项,Intel编译器有能力判断哪些地方可以通过合适的数据访问模式激活硬件数据预读机制,哪些地方需要额外添加数据预读指令。

产生调试信息

通过使用/Zi选项产生调试信息以帮助调试。默认为关闭。在本程序的开发阶段,打开此选项。在开发完成后关闭此选项。

使用全局优化

通过使用/Og选项打开编译器的全局优化功能。该选项需要在本程序不同的开发阶段分别尝试是否打开以确定最优优化选项。

针对Windows程序优化

通过使用/GA选项可以打开Intel编译器的针对Windows程序优化的功能。其实通过打开/GA选项,Intel可以提高访问Windows下thread-local storage(TLS)变量的速度。TLS变量通过__declspec(thread)来定义。在本程序中,并不打算使用TLS变量。但还是打开/GA选项。

内联函数扩展

Intel编译器可以通过/Obn来定义内联函数的扩展级别。当n为0禁止用户定义的内核函数的扩展。当n为1时,根据用户定义的inline关键字进行扩展。当n为2时,根据Intel编译器的自动判断进行扩展。本次程序使用/Ob2选项。

FTZ与DAZ

在计算机内浮点数是由尾数和指数组成的。尾数通常被规范化成[1,2)之间。但是当数字接近0时,由于其指数已经无法将尾数规范成[1,2)之间,所以需要在尾数表示成0.0000xx的形式。这种表示形式称为不规范的形式。其会影响CPU的浮点计算速度。并且由于这种数非常接近0,所有有时将其表示成0并不会影响计算的结果。所以CPU的浮点控制器有2个用于控制对于不规范数处理的选项。FTZ用于将计算结果中的不规范数表示成0,DAZ用于在读入不规范数时将其表示成0。

Intel编译器提供了内置的宏来方便用户设置这两个模式。

这两个宏分别是_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON)和_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON)。用户在程序中设置了这两个模式将有助于提高浮点计算速度。

但是实际上对于本程序,由于已经使用了/O3以及SSE指令集优化。所以Intel编译器已经设置好了FTZ模式,用户不必另外设置FTZ。并且由于本程序中所有的数都是计算得来的,所以只要计算时使用了FTZ,那读取数据时就不会碰到不规范的数据,所以用户也没必要设置DAZ。

编译器报告

编译器报告虽然不能直接提供优化,但是却可以让用户了解编译器处理程序的信息,给用户更改源代码提供了很多有用的信息。对于本程序,向量化是非常重要的一步,而编译器报告可以指出某个地方是由于什么原因造成没有向量化。所以本使用使用/Qvec-report3参数对向量优化进行报告。

使用Intel编译器函数进行精确时间测量

Intel编译器提供了许多特殊的函数。这类函数一般都对应一条或者几条汇编语言。其可以让用户以比汇编语言方便的方式写出性能接近汇编语言的代码。其中最主要的是对SIMD类指令的支持。当然其中还有很多其他功能的函数。比如_rdtsc()函数。

需要注意的是要使用这些函数必需打开/Oi选项。这个选项默认是打开的。

当程序需要进行精确时间测量,比如优化后需要知道某段特定的代码到底快了多少毫米时,使用Windows的时间函数已经无法满足精度要求。这是用户可以使用Intel VTune Analyzers进行测量(具体使用方法将在后面介绍)。其实CPU已经提供了一个特殊的机器指令rdtsc,使用这条指令可以读出CPU自从启动以来的时钟周期数。由于现在的CPU主频已经是上GHz了。所以,其计时精度可以达到纳秒级。Intel提供的_rdtsc()函数使得用户不必再使用汇编语言,可以像调用函数一样得到CPU的时钟周期数。例子代码如下:

注:以下代码摘自“Intel C++ Compiler Documentation”

#include 

优化结果

经过以上编译器选项的调整,程序的运行速度已经达到了2.25秒。

参考资料

英特尔多核平台编程优化大赛报告 - 大CC - 博客园​www.cnblogs.com
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Intel C++ 编译器Windows版》(Intel.C.Plus.Plus.Compiler.v10.0.026)[Bin] 软件版权归原作者及原软件公司所有,如果你喜欢,请购买正版软件 常驻服务器 : DonkeyServer No2, 7x24, 根据工作需要暂停 [版本说明] 截止到2007-08-15为最新版, 仅包含Windows平台, 支持 IA32 / Intel64 / IA64处理器 [病毒检测] NOD32 v2.7 2007-08-15 [安装测试] Windows 2003 SP2 / Visual Studio 2005 SP1 [产品主页] [ http://www.intel.com/cd/software/products/...9578.htm ] [产品简介] 个人翻译, 以原版英文为准: 概要: -------------------------------------------------------------------------------- Intel C++编译器专业版为创建多线程应用程序提供最好的支持。只有专业版才提供对高级优化、多线程和处理器支持(?)。包括自动处理器派发、向量化、自动并行处理、OpenMP*、数据预取、循环展开,还有为并行化、数学运算和多媒体库而高度优化的C++模版。 专业版把高效的编译器Intel® Threading Building Blocks (Intel® TBB), Intel® Integrated Performance Primitives (Intel® IPP) and Intel® Math Kernel Library (Intel® MKL)整合到了一起。虽然这些库也可以单独获取,但是专业版在一个显著折扣价位上为构建稳定高效的并行代码提供了一个强大的基础。 标准版编译器和专业版有着相同的效能和特性, 但是不提供多线程库。 特性: -------------------------------------------------------------------------------- 效能: 考虑使用Intel C++编译器专业版来最佳化效能。内间的优化技术和多线程支持帮助您创建可以在最新的多核处理器上运行best的代码。 高级优化特性: 使用IntelC++编译器Windows版编译的软件可以受益于高级优化特性, 这里有一些简要介绍, 并且链接到完整描述: * Multi-Threaded Application Support, including OpenMP and auto-parallelization for simple and efficient software threading. * Auto-vectorization 并行化代码来利用最新处理器的SSE指令集构架(SSE, SSE2, SSE3, SSSE3, and SSE4)。 * High-Performance Parallel Optimizer (HPO)(高效能并行优化器) 重新组织和优化循环来确定auto-vectorization, OpenMP, or auto-parallelization 最好的利用处理器的缓存、内存访问、SIMD指令集和多核能力。这个由10.0版本而来得新的革命性的能力,组合了向量化、并行化和循环转化到一个比先前分散模块更快、更有效率和更可靠的单个过程。 * Interprocedural Optimization (IPO) 大幅的改善了被频繁使用的中小规模函数的效能,尤其是在循环内包含调用的程序。这个优化器的分析能力还可以对代码弱点和代码错误给出反馈,诸如未初始化的变量或者OpenMP API issues这些严格依赖编译器前端的编译器不能检测到的状况。 * Profile-guided Optimization (PGO) 通过减少指令缓存thrashing、重新组织代码布局、收缩代码大小和降低分支预测失败来改善程序效能。 * Optimized Code Debugging with the Intel® Debugger(使用Intel调试器调试优化后的代码)改善了为Intel架构优化代码的调试过程的效率. 本版本新特性: -------------------------------------------------------------------------------- 此Intel C++编译器Windows版本构建于一个winning foundation之上。它使您能够为下一代硬件创建下一代应用。 改善的效能和Threading * 新的并行/循环优化器 * 改善的C++优化 * 异常处理和类层次分析 安全监测和诊断 * 缓冲区溢出静态验证 * OpenMP API 验证 VISTA 和 Visual Studio 2005 支持 优化报告 支持最新的多核处理器 * Intel® Core™2 Duo processor * Intel® Core™2 Quad processor * Quad-Core Intel® Xeon® processor 5300 series * Dual-Core Intel® Xeon® processor 3000 series * Dual-Core Intel® Xeon® processor 5000 series * Dual-Core Intel® Xeon® processor 7000 series * Dual-Core Intel® Itanium® 2 processor 提供专业版本 Advanced Optimization Features in Depth -------------------------------------------------------------------------------- ... ... 兼容性和适应性 -------------------------------------------------------------------------------- ... ... 可与Microsoft Visual Studio 2005, Visual Studio .NET 2002/2003, and Visual Studio 98集成,并提供扩展的32位和64位多核Intel处理器支持。 Intel C++ 编译器提供下列语言一致性 * ANSI/ISO C 语言标准一致性 (ISO/IEC 9899:1990) * ANSI/ISO C++语言标准一致 (ISO/IEC 14882:1998) * OpenMP 规范版本 2.5 系统需求

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值