自編教材分享:第九章—向量化指導(dǎo)命令



向量化指導(dǎo)命令
OpenMP指導(dǎo)語(yǔ)句中有兩種支持向量化語(yǔ)句,分別為#pragma omp simd和#pragma omp for simd。其中#pragma omp simd指導(dǎo)語(yǔ)句對(duì)循環(huán)進(jìn)行向量化是單線(xiàn)程的數(shù)據(jù)級(jí)并行,而#pragma omp for simd結(jié)合了for和simd兩個(gè)指導(dǎo)命令同時(shí)進(jìn)行并行化和向量化,具體是既將所有迭代的計(jì)算任務(wù)分配給各個(gè)線(xiàn)程,又進(jìn)一步將每個(gè)線(xiàn)程執(zhí)行的計(jì)算任務(wù)進(jìn)行向量化。
如圖所示,OpenMP使用2個(gè)線(xiàn)程在128位寄存器上對(duì)4個(gè)單精度數(shù)進(jìn)行加法計(jì)算,在串行執(zhí)行時(shí),只能使用1個(gè)線(xiàn)程計(jì)算一次加法運(yùn)算,其余線(xiàn)程則處于空閑狀態(tài);在并行執(zhí)行時(shí),使用2個(gè)線(xiàn)程,每個(gè)線(xiàn)程執(zhí)行一次加法運(yùn)算;在向量化執(zhí)行時(shí),只能使用1個(gè)線(xiàn)程,但這1個(gè)線(xiàn)程內(nèi)可以使用SIMD單元進(jìn)行4次加法運(yùn)算;在并行向量化執(zhí)行時(shí),除了使用全部2個(gè)線(xiàn)程之外,每個(gè)線(xiàn)程還可以計(jì)算4次加法運(yùn)算,并行區(qū)一共計(jì)算8次加法運(yùn)算,可明顯提升程序的性能。

與指導(dǎo)命令simd配套的子句中,aligned用于數(shù)據(jù)的對(duì)齊;collapse用于循環(huán)嵌套的合并調(diào)度;部分子句lastprivate、linear、private和reduction用于設(shè)定子線(xiàn)程或SIMD通道的數(shù)據(jù)共享變量,其中SIMD通道是指在指定向量長(zhǎng)度的寄存器上可同時(shí)處理的數(shù)據(jù)個(gè)數(shù);子句linear(list[ : linear-step])表示變量列表中的變量xi對(duì)于每次迭代而言是私有的,它與循環(huán)迭代次數(shù)i之間存在線(xiàn)性關(guān)系xi=x0+i*step,step的值在執(zhí)行simd結(jié)構(gòu)期間不變,默認(rèn)為1;其它子句如simdlen和safelen用于設(shè)定向量長(zhǎng)度限制,子句safelen(length)通過(guò)限制程序的向量長(zhǎng)度來(lái)維持循環(huán)依賴(lài),從而保證運(yùn)行結(jié)果的正確性,其中l(wèi)ength為在不打破循環(huán)依賴(lài)情況下支持并行執(zhí)行循環(huán)迭代的最大數(shù)目;子句simdlen(length)用于指定向量長(zhǎng)度為length,即向量化后每次迭代執(zhí)行的運(yùn)算相當(dāng)于未向量化時(shí)執(zhí)行n次,其中n必須是2的冪。
除直接使用simd指導(dǎo)語(yǔ)句外,OpenMP還能在各個(gè)循環(huán)之間沒(méi)有依賴(lài)的前提下,采用for simd復(fù)合指導(dǎo)語(yǔ)句同時(shí)進(jìn)行并行化和向量化,這時(shí)每個(gè)線(xiàn)程能夠充分利用處理器核心進(jìn)行數(shù)據(jù)級(jí)并行,進(jìn)一步提升程序的性能。for simd指導(dǎo)語(yǔ)句的語(yǔ)法方法如下,由于其由指導(dǎo)命令for和simd組合而來(lái),因此其配套子句為這兩個(gè)指導(dǎo)命令配套子句的并集。
simd 指導(dǎo)語(yǔ)句
for simd 指導(dǎo)語(yǔ)句
相較于程序的串行執(zhí)行,添加simd指導(dǎo)語(yǔ)句進(jìn)行向量化操作后,由系統(tǒng)SIMD單元長(zhǎng)度為256bit支持8個(gè)浮點(diǎn)型數(shù)據(jù)同時(shí)運(yùn)算可知,理論上加速比能夠達(dá)到8,但實(shí)際測(cè)試得到程序加速比達(dá)到了14,在僅添加-O3選項(xiàng)編譯測(cè)試后,發(fā)現(xiàn)這是因?yàn)槭褂?O3編譯選項(xiàng)的同時(shí)開(kāi)啟了其他隱含的編譯優(yōu)化,使得程序的性能又獲得了進(jìn)一步提升。

