向量化的方法.doc_第1頁
向量化的方法.doc_第2頁
向量化的方法.doc_第3頁
向量化的方法.doc_第4頁
向量化的方法.doc_第5頁
已閱讀5頁,還剩3頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

使用英特爾編譯器進行自動向量化 作者:Yang Wang (Intel)自動向量化是英特爾編譯器提供的一個可以自動的使用SIMD指示的功能。 在處理數(shù)據(jù)時, 編譯器自動選擇MMX, Intel Streaming SIMD 擴展(Intel SSE, SSE2, SSE3 和SSE4)等指令集, 對數(shù)據(jù)進行并行的處理。 使用編譯器提供的自動向量化功能是提高程序性能的一個非常有效的手段。自動向量化在IA-32和Intel 64的平臺上均提供很好的支持。英特爾編譯器提供的自動向量化相關(guān)的編譯選項如下所示?!?Q”開頭的選項是針對Windows平臺的, “-“開頭的選項是針對Linux*和Mac平臺的。-x, /Qx按照該選項指定的處理器類型生成相應(yīng)的優(yōu)化代碼。 比如-xSSE3, 該選項指定編譯器生成Intel SSE3指令的代碼。 又比如-xSSE3_ATOM, 該選項針對Intel Atom 處理器進行優(yōu)化。-ax, /Qax如果指定該選項, 在生成的單一目標(biāo)文件中, 不但會生成專門針對指定的處理器類型進行優(yōu)化的代碼, 同時也生成通用的IA-32架構(gòu)的代碼。 該選項主要是為了生成代碼的兼容性考慮。-vec, /Qvec打開或者關(guān)閉編譯器的向量化優(yōu)化。 默認情況下自動向量化是打開的。-vec-report, /Qvec-report該選項用戶控制在編譯過程中產(chǎn)生的向量化消息報告。編譯器提供的自動向量化優(yōu)化默認情況下是打開的。 在編譯過程中我們可以使用-vec-report選項來打開向量化診斷消息報告。 這樣編譯器可以告訴我們有哪些循環(huán)被向量化了, 有哪些循環(huán)沒有被向量化已經(jīng)無法向量化的原因。在編譯程序的過程中, 有時候我們會發(fā)現(xiàn)編譯器報告說某個循環(huán)無法被向量化。 很多時候無法向量化的原因都是因為循環(huán)中存在的變量依賴關(guān)系。 有時候我們可以修改程序來消除這種依賴關(guān)系,有的時候我們可以使用編譯器提供的一些編譯指示來顯示的告訴編譯器如何處理這種依賴關(guān)系。 即使在某個循環(huán)已經(jīng)可以被自動向量化的時候, 使用編譯器提供的對向量化的語言支持和編譯指示還可以提高編譯器向量化的效率, 提高程序執(zhí)行的性能。下面我們來詳細解釋一下編譯器提供的編譯指示以及這些指示對編譯器編譯的影響。在Intel編譯器中, 我們提供下面這樣一些對自動向量化的語言支持和編譯指示。_declspec(align(n)指導(dǎo)編譯器將變量按照n字節(jié)對齊_declspec(align(n,off)指導(dǎo)編譯器將變量按照n字節(jié)再加上off字節(jié)的編譯量進行對齊restrict消除別名分析中的二義性_assume_aligned(a,n)當(dāng)編譯器無法獲取對齊信息時,假定數(shù)組a已經(jīng)按照n字節(jié)對齊#pragma ivdep提示編譯器忽略可能存在的向量依賴關(guān)系#pragma vector aligned|unaligned|always指定向量化的方式#pragma novector指定不做向量化下面我們就這些編譯指示做一些詳細的了解。 _declspec(align(n)首先我們來看看如何使用_declspec(align(n)來進行自動向量化。該指示主要是用來告訴編譯器一個變量的對齊方式。 當(dāng)一個變量的對齊方式為16字節(jié)對齊時, 生成的向量化指令是最高效的。 當(dāng)編譯器不知道一個變量的對齊方式的時候, 他可能沒有辦法對該變量的使用進行向量化, 或者編譯器會不得不生成條件語句來進行有條件的向量化。 我們來看一下下面這個例子。File: vec1.cchar a;void vec1(void)int i;for(i=0;i1024;i+)ai = 1;使用下面命令編譯該程序:icl vec1.c -O2 -c /Qvec-report:3這時編譯器輸出:vec1.cvec1.c(10) (col. 2): remark: LOOP WAS VECTORIZED.我們可以看到編譯器對上面這個程序進行了自動向量化。 但是實際上, 由于編譯器不知道a的對齊字節(jié)數(shù), 所以他對變量a數(shù)據(jù)進行了一些條件處理。 我們可以在編譯的時候加上-S選項來查看編譯器生成的匯編代碼。 實際上, 編譯器對該程序做了如下處理:temp = a&0x0f;if(temp != 0)temp = 16-temp;for(i=0;itemp;i+) ai = 1;/*下面是對齊的訪問*/for(i=temp;i1024;i+) ai = 1;如果我們指定了a的對齊方式, 比如我們使用_declspec(align(16)來定義變量a, 如下所示:_declspec(align(16) char a;void vec1(void)int i;for(i=0;i1024;i+)ai = 1;對于上面這段程序, 編譯器做了自動向量化。 如果我們檢查生成的匯編代碼可以發(fā)現(xiàn),對于a的對齊方式的條件處理代碼已經(jīng)不見了。正確使用_declspec(align(n)以及其他align相關(guān)編譯指示可以幫助編譯器進行自動向量化以及提高編譯器自動向量化的效率。 restrict使用restrict關(guān)鍵字可以顯式的告訴編譯器取消指針之間的二義性。 我們還是用下面這個例子來說明restrict的使用。File: vec2.cvoid vec2(char* a, char* b, int n)int i;for(i=0;in;i+)ai = bi;使用以下命令進行編譯:icl vec2.c -O2 -c /Qvec-report:3編譯器輸出:vec2.crestrict.c(5) (col. 2): remark: LOOP WAS VECTORIZED.restrict.c(5) (col. 2): remark: loop skipped: multiversioned.此時編譯器輸出multiversioned向量化代碼, 對同一個循環(huán)產(chǎn)生了多個版本的實現(xiàn)。實際上編譯器對代碼進行了條件處理, 如下所示:void vec2(char* a, char* b, int n)int i;if(a+nb | b+na)for(i=0;in;i+) ai = bi; /*向量化循環(huán)*/elsefor(i=0;in;i+) ai = bi; /*串行循環(huán)*/可以看出,由于編譯器不知道指針a 和b之間是否存在重疊, 所以他對循環(huán)進行了條件處理。 如果我們從語義上能夠保證a和b是不會發(fā)生重疊的, 那么我們就可以使用restrict關(guān)鍵字來顯式的告訴編譯器這一點。void vec2(char* restrict a, char* restrict b, int n)int i;for(i=0;in;i+)ai = bi;此時編譯器輸出沒有multiversioned。restrict.crestrict.c(5) (col. 2): remark: LOOP WAS VECTORIZED.注意C90里面不支持restrict關(guān)鍵字, 在windows平臺編譯的時候我們需要加上選項/Qrestrict來讓編譯器認識restrict關(guān)鍵字。 #pragma vector使用#pragma vector編譯指示來顯式告訴編譯器使用某種方式來進行自動向量化。 比如在下面這個例子中, 我們可以保證變量a的地址是16字節(jié)對齊的,那么我們就可以使用#pragma vector aligned來顯式的告訴編譯器不需要考慮非對齊的情況。這樣產(chǎn)生的向量化代碼是最高效的。File: vec3.c#include void vec3(void)int i;char* a=_aligned_malloc(1024, 16);#pragma vector alignedfor(i=0;i1024;i+)ai = 1;在上面這個例子中, 如果我們不加上#pragma vector aligned, 編譯器會對循環(huán)進行條件處理后的向量化。 大家可以對比一下兩種情況下生成的匯編代碼的區(qū)別。請注意我們在使用#pragma vector aligned的時候需要保證被處理變量的對齊方式是16字節(jié)對齊的, 否則在使用了該編譯指示后可能會產(chǎn)生錯誤的結(jié)果。在上面這個例子中, 我們稍作如下修改:#include void vec3(void)int i;char* a=_aligned_malloc(1024, 16);char* b = a+1;#pragma vector alignedfor(i=0;i1023;i+)bi = 1;循環(huán)中的b的地址不是16字節(jié)對齊的, 但是如果我們還是按照aligned的方式來做向量化, 產(chǎn)生的結(jié)果是編譯出來的可執(zhí)行程序運行時異常。 在上面的例子中, 我們需要使用#pragma vector unaligned 編譯指示來正確的引導(dǎo)編譯器。 #pragma ivdep使用#pragma ivdep顯式的告訴編譯器忽略向量之間可能存在的依賴關(guān)系。參考下面這個例子。File: vec4.cvoid vec4(int* a, unsigned int n, unsigned int m)int i;for(i=0;in;i+)ai = ai+m;使用編譯器編譯該程序:icl vec4.c O2 -c /Qvec-report:3編譯器輸出:vec4.cvec4.c(6) (col. 2): remark: loop was not vectorized: existence ofvector dependence.vec4.c(7) (col. 3): remark: vector dependence: assumed ANTI dependence between a line 7 and a line 7.vec4.c(7) (col. 3): remark: vector dependence: assumed FLOW dependence between a line 7 and a line 7.vec4.c(7) (col. 3): remark: vector dependence: assumed FLOW dependence between a line 7 and a line 7.vec4.c(7) (col. 3): remark: vector dependence: assumed ANTI dependence between a line 7 and a line 7.如果我們可以保證a0到an-1和am到am+n-1之間不存在重疊, 那么我們就可以使用#pragma ivdep來顯式的告訴編譯器可以忽略ai和ai+m之間的依賴關(guān)系, 修改程序如下:void vec4(int* a, unsigned int n, unsigned int m)int i;#pragma ivdepfor(i=0;i Compiler Options. Many library routines that are part of Intel Compiler are more highly optimized for Intel microprocessors than for other microprocessors. While the compilers and libraries in Intel Compiler offer optimizations for both Intel and Intel-compatible microprocessors, depending on the options you select, your code and other factors, you likely will get extra performance on Intel microprocessors.While the paragraph above describes the basic optimization approach for Intel Compiler, with respect to Intels compilers and associated libraries as a whole, Intel Compiler may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include Intel Streaming SIMD Extensions 2 (Intel SSE2), Intel Streaming SIMD Extensions 3 (Intel SSE3), and Supplemental Streaming SIMD Extensions 3 (Intel SSSE3) instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors.Intel recommends that you evaluate other compilers to determine which best meet your requirements.使用#pragma simd進行自動向量化#pragma simd該編譯指示(SIMD)是12.0編譯器最新提供的功能。他可以強制性的讓編譯器做自動并行化。 對于其他編譯指示比如#pragma ivdep來說, 如果編譯器編譯時發(fā)現(xiàn)用戶提供的編譯指示條件不滿足, 那么編譯器是不會根據(jù)編譯指示來進行自動向量化的。也就是說, 編譯器實際上還是會進行編譯時的依賴關(guān)系檢查。 而對于#pargam simd來說, 無論編譯時條件如何, 編譯器總是會進行自動向量化。這種情況下, 用戶需要自己去保證被向量化的循環(huán)上語義的正確性, 需要自己保證被向量化變量之間的依賴關(guān)系的正確性。我們用一個例子來說明編譯器的行為區(qū)別。File vec5.cvoid vec5(int* a, int n)int i;for(i=0;in;i+)ai = ai-1;對上面這個例子, 由于存在flow-dependence關(guān)系, 程序中的循環(huán)明顯是不能被向量化的。vec5.cC:testvec5.c(6) (col. 2): remark: loop was not vectorized: existence of vector dependence.C:testvec5.c(7) (col. 3): remark: vector dependence: assumed FLOW dependence between a line 7 and a line 7.此時我們加上#pragma ivdep想讓編譯器忽略循環(huán)之間的依賴關(guān)系(當(dāng)然這種操作是不符合原始語義的)。void vec5(int* a, int n)int i;#pragma ivdepfor(i=0;in;i+)ai = ai-1;這時編譯該程序, 程序的輸出與不加#pragma ivdep時相同。 編譯器在進行編譯的時候檢查發(fā)現(xiàn)了循環(huán)之間不可避免的依賴關(guān)系, 即使有#pragma ivdep存在, 編譯器也還是不會對該循環(huán)進行向量化。如果我們加上#pragma simd, 重新編譯程序:void vec5(int* a, int n)int i;#pragma simdfor(i=0;in;i+)ai = ai-1;這時編譯輸出:vec5.cC:testvec5.c(6) (col. 2): remark: SIMD LOOP WAS VECTORIZED.程序中的循環(huán)被向量化了, 但是此時我們顯然不會得到一個正確的結(jié)果。我們再看一個用SIMD的正確的例子。 比如下面這個程序:void vec5(int* a, int n, int m)int i;for(i=0;in;i+)ai = ai-m;編譯該程序: icl /O2 /c /Qvec_report:3, 編譯器會報告該程序因為存在向量依賴關(guān)系而不能被向量化。在該程序中, 如果我們可以保證m大于等于4, 那么我們可以加入#pragma simd指示如下所示:void vec5(int* a, int n, int m)int i;#prgama simdfor(i=0;i Compiler Options. Many library routines that are part of Intel Compiler are more highly optimized for Intel microprocessors than for other microprocessors. While the compilers and libraries in Intel Compiler offer optimizations for both Intel and Intel-compatible microprocessors, depending on the options you select, your code and other factors, you likely will get extra performance on Intel microprocessors.While the paragraph above describes t

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論