使用Intel 向量化编译器优化性能(1)

原创 2003年05月13日 11:02:00

使用Intel 向量化编译器优化性能(1)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

本文节选翻译自Intel网站

 

使用Intel c++编译器的时候,怎么也找不到相关的资料可以参考,在Intel的网站找到了一些教程,我C++的水平很一般,对这个编译器的使用也是刚入门,大家看了请多指正,这是第一部分,余下的我会在这几天继续整理完.

 

学习如何增强c/c++以及Fortran代码在windows和Linux下的性能,使用Intel的向量化编译器来为特定的循环操作自动产生SIMD代码,这些SIMD指令包括MMX/SIMD Extensions /SIMD Extensions 2.

 

1.       什么是向量器

向量器是intel c++/Fortran编译器的一个特性,使用intel向量编译特性通过自动生成SIMD代码加速你的代码中特定的循环, 这些SIMD指令包括MMX/SIMD Extensions /SIMD Extensions 2.

 

2.       什么是向量化程序

a)       主要改善性能的地方

当函数包含大量循环时通过使用向量化编译器使用SIMD指令能够获取较大的性能上的提高,一段以向量化循环为特征的程序足以快过那些同样运行方式的一般的程序或类库.对比一个向量化的循环和一个同样方式的标量循环,向量化会提供等同于使用底层汇编实现这循环的性能(通常使用在使用Streaming SIMD Extensions时会有25%-40%的性能提高).向量器也可能打开这些循环插入一些预取和 streaming store(不知道怎么翻译) 代码在你的循环中,这也可能获得一些额外的性能上的提高.

b)       使用Intel的编译器可以使你从单调乏味的优化工作中解脱出来,编译器可以节省你很多时间,可以代替你做更多的工作.

c)       Intel编译器从4.5版本开始支持向量化,5.0版本增强了向量化的功能包括performing simple statement reordering automatically(这是什么,也不知道)和对SIMD2的支持

 

3.       为什么要使用向量器

a)       提高性能, 比如向量化一个有浮点操作的并被频繁调用的循环将会极大提高程序的性能

b)       编写单一版本的代码, 减少使用汇编使编码工作简化,较少的汇编意味着会大大减少你为特定的系统编程的工作,你的程序将很容易升级并使用于最新的主流系统而不必重新编写那些汇编代码.

 

4.       什么样的循环是可以向量化的

a)       对于一个循环,如果编译器认为循环内的每一个语句都没有依赖于另一个语句并且没有循环的依赖关系,那么这个循环就是向量的.换句话说,每一个语句必须能独立执行,读写数据的操作必须中立于循环的每次迭代

        看这个循环

for (int i=0; i<1000; i++) {
s1: a[i] = b[i] * T + d[i] ;
s2: b[i] = a[i] + b[i])/2;
s3: c = c + b[i];
}

        如果等价于下面的操作

for (int i=0; i<1000; i++) a[i] = b[i] * T + d[i] ;
for (int i=0; i<1000; i++) b[i] = (a[i] + b[i])/2;
for (int i=0; i<1000; i++) c = c + b[i];

那么就认为这个循环是可以被向量化的.

再看一个例子

 

for (int i=1; i<1000; i++)

{
s1: a[i] = a[i-1] * b[i];
}

无论如何,这个循环是不能被向量化的,因为a[i]在每次迭代中都读取了前一次迭代中的a[i-1].我们称这是一个交叉迭代的数据依赖或者”flow dependence”,这样的循环不能被编译器向量化.

 

假定在第一个例子中使用的是浮点数据-向量器能够通过使用SIMD Extensions同时操作4个浮点数,在这里,为了能够向量化,这个循环的次数必须大于4.

 

b)       向量器只能作用在最内层的循环

在一个嵌套的循环中,向量器只能尝试向量化最内层的循环,查看向量器的输出信息可以知道循环是否能被向量化以及原因,如果影响性能的关键循环没有向量化,你可能需要做一些更深层的打算,比如像下面描述的内容那样来帮助向量器做出正确的决定.

 

c)       向量化不是并行化

看这个例子

 

for (int i=0; i<1000; i++)

{
s1: a[i] = b[i] * T + d[i] ;
s2: b[i] = (a[i] + b[i])/2;
s3: c = c + b[i];
}

 

    这个向量化程序依次s1,s2,s3执行所有的循环迭代.

    并行化意味在语句的不同的迭代循环中可能被另一个处理过程所干扰,如果语句请求共享资源(比如读写同一个数据),那这个输出就不能保证正确,所以这个循环是不能正确向量化的.

 

5.       如何打开向量器

参数

Windows*

Linux*

在编译器指定cpu类型时打开向量器

/Qx[M,K,W]

-x[M,K,W]

打开向量器并自动检测cpu类型,编译器能生成向量化的代码为最新的IA-32处理器,但同时也生成非向量化的代码供旧型号的处理器使用,这样使执行文件可以运行在多种处理器上

/Qax[M,K,W]

-ax[M,K,W]

-W 打开对P4的Streaming SIMD Extensions 2的支持, -K打开对Pentium® III process的支持,-M是对MMX技术提供支持

6.       关于#pragma ivdep和restrict的使用

a)       为了向量化一个包含或可能包含依赖关系的循环,加上#pragma ivdep (ignore vector dependencies),如果需要的话.

Void foo(int k)

{
#pragma ivdep

for(int j=0; j<1000; j++)

{

a[j] = b[j+k] * c[j];
b[j] = (a[j] + b[j])/2;
b[j] = b[j] * c[j];

}

}

当向量化这个循环时.编译器会认为数组b依赖了交叉迭代,原因就是是使用了变量k,如果你知道k不会干涉数据访问,加上#pragma ivdep向量器忽略向量的依赖性并尝试进行向量化,根本说,你必须知道这个依赖性是什么,并确信他们不会成为问题

 

b)       使用指针的循环

使用指针的循环可能造成依赖性,如果为了向量化这样的循环,可以使用restrict关键字,如果需要的话

Void foo(float *restrict a, float *restrict b, float * restrict c)

{

for(int j=0; j<1000; j++)

{

a[j] = b[j] * c[j];

b[j] = (a[j] + b[j])/2;

b[j] = b[j] * c[j];

}

}

注意,使用了restrict关键字旧需要使用/ Qrestrict开关.如果不使用restrict关键字,编译器会认为数组的引用可能有交叉迭代的依赖性

这是因为指针在循环中用来访问数据,编译器无法知道是否指向了相同的地址(一般就是别名),为了安全必须阻止这样程序向量化, restrict关键字告诉编译器指针指向的地址是受限的,只能通过这个指针访问,换句话说,这里没有别名

 

7.       Verbose 模式参数

windows下使用/Qvec_report[0,1,2,3]参数来产生详细的向量化报告,在Linux下使用-vec_report[0,1,2,3]参数, [0,1,2,3]指定输出信息的详细等级,在最详细的等级3,编译器会指出向量器是产生代码的具体信息.

 

下面是一次开启了向量器的编译操作的部分输出信息:

C:/TEMP/Text1.cpp(16) : (col. 1) remark: <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />LOOP WAS VECTORIZED.

Below is an example of vectorizer output using the level 3 switch.

char *p;

p = "aeiou";

while (*p++) {

cout << *p;

}

C:/TEMP/Text1.cpp(20) : (col. 1) remark: loop was not vectorized: nonstandard loop is not a vectorization candidate.

float x[100], y[100];

int z[100];

for(int j=0; j<100; j++)

{

x[j] = y[j] + 3;

z[j] = z[j+1];

}

C:/TEMP/Text1.cpp(29) : (col. 5) remark: loop was not vectorized: mixed data types.

float x[100], y[100];

int z[100];

for(int j=0; j<100; j++)

{

x[j] = y[j] + 3;

y[j+1] = z[j+1];

}

C:/TEMP/Text1.cpp(26) : (col. 1) remark: loop was not vectorized: existence of vector dependence.

注意这里有2处问题,2处循环都有向量依赖性,还有一个循环有数据类型不一致的问题,向量器会根据检测到的这些问题的优先等级给出信息.

 

待续………………….

GCC源码分析(5):自动向量化遍

转自:http://blog.chinaunix.net/uid-13800995-id-67986.html
  • u014529578
  • u014529578
  • 2014年10月30日 23:00
  • 324

GCC中的自动向量化(1)

GCC中的自动向量化(1) 本文是阅读Dorit Naishlos的文章“Autovectorization in GCC”时做的笔记。 在使用了语法树上的静态单赋值(tree SSA)优化框架之...
  • u012033027
  • u012033027
  • 2016年08月18日 17:00
  • 1300

intel向量化指令在矩阵乘应用中的评估

随着机器学习等人工智能技术的飞速发展,矩阵乘法的应用越来越多,intel芯片先后提供了不同系列的向量指令,包括mmx、sse、avx等,支持simd操作。后来为了更好地支持矩阵乘法,又增加了fma(F...
  • u012033027
  • u012033027
  • 2017年02月13日 22:05
  • 968

H.264 软/硬编码器 画质量化分析评测

第1页:前言——视频压缩无处不在 H.264 或者说 MPEG-4 AVC 是目前使用最广泛的高清视频编码标准,和上一代 MPEG-2、h.263/MPEG-4 Part4 相比,它的压...
  • sz_liao
  • sz_liao
  • 2013年12月24日 11:42
  • 1846

【量化入门】通过几种常见的量化策略框架,学习量化炒股

阅读原文:http://club.jr.jd.com/quant/topic/1176040 量化选股,就是通过量化思想及配套的计算机程序化来实现选股(如何选择好的股票)和择时(如何在合适的时间...
  • JDquant
  • JDquant
  • 2017年03月15日 20:48
  • 4244

为什么要自建量化交易平台?

量化交易平台概述   量化交易是指借助现代统计学和数学的方法,利用计算机技术来进行交易的投资方式。它从历史数据中选择经数量模型验证的大概率事件制定策略,通过严格执行来获得持续稳定的超额回报。它具有严...
  • IAlexanderI
  • IAlexanderI
  • 2017年04月16日 22:27
  • 1465

基于C++/Python的免费开源量化研究框架-Hikyuu Quant Framework

前段日子终于将一直个人使用的量化交易回测工具打包发布,为开源做些贡献。一个人制作安装包、写文档、建网站,还真是点累,但总算是搭了个基础,可以慢慢补充完善。现在量化回测工具、免费云平台不少,各有千秋,H...
  • KongDong
  • KongDong
  • 2017年05月17日 22:26
  • 1296

优化CNNs--量化方法进展介绍

介绍了最新的几种通过量化方法来优化卷积神经网络的网络结构
  • dnvtmf
  • dnvtmf
  • 2017年07月09日 18:31
  • 758

GCC源码分析(5):自动向量化遍

转自:http://blog.chinaunix.net/uid-13800995-id-67986.html
  • u014529578
  • u014529578
  • 2014年10月30日 23:00
  • 324

seo核心seo操作如何度量化

如果不能度量就无法进行改进,所以度量化或数据化是网站分析和网站研究必须进行的一个方面,seo也不能例外。我在上篇文章说了,传统意义的seo理论是基于算法,研究算法我个人的观点就是研究特征权重的识别和处...
  • u013569832
  • u013569832
  • 2014年02月05日 12:25
  • 585
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用Intel 向量化编译器优化性能(1)
举报原因:
原因补充:

(最多只允许输入30个字)