欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
GCC中SIMD指令的應用方法
作者:錢(qián)浙濱 2005-01-19 09:45:57 來(lái)自:IBM DW中國
X86架構上的多媒體應用開(kāi)發(fā),如果能夠使用SIMD指令進(jìn)行優(yōu)化, 性能將大大提高。目前,IA-32的SIMD指令包括MMX,SSE,SSE2等幾級。 在GCC的開(kāi)發(fā)環(huán)境中,有幾種使用SIMD指令的方式,本文逐一介紹。
X86的SIMD指令 ...simd instrucitons in X86
IA-32 Intel體系結構的指令主要分為以下幾類(lèi) [1]:
* 通用
* x87 FPU
* MMX技術(shù)
* SSE/SSE2/SSE3擴展
MMX/SSE類(lèi)擴展引入了SIMD(單指令多數據)的執行模式,可用于加速多媒體應用。 下面簡(jiǎn)要介紹一下這些指令的執行環(huán)境和特征。
* 8個(gè)32位通用寄存器可為各個(gè)SIMD擴展所使用;
* MMX:8個(gè)64位MMX寄存器(mm0 - mm7),也可為各SSE擴展所使用;
o 數據為整數,最多支持兩個(gè)32位
o 運算中沒(méi)有寄存器能夠進(jìn)行溢出指示
* SSE:8個(gè)128位xmm寄存器,MXSCR寄存器,EFLAGS寄存器
o 支持單精度浮點(diǎn)
o MXSCR含有rounding, overflow標志
o 支持64位SIMD整數
* SSE2:執行環(huán)境同sse
o 雙精度浮點(diǎn)
o 128位整數
o 雙—單精度轉換
* SSE3:與Inte Prescott處理器一同發(fā)布不久,共13條指令
o 主要增強了視頻解碼、3D圖形優(yōu)化和超線(xiàn)程性能
MMX技術(shù)出現最早,目前幾乎所有的X86處理器都提供支持,包括嵌入式X86, 所以下面的討論主要基于MMX,但方法完全適用于SSEn, 包括像AMD的3D Now等其它SIMD擴展。
MMX指令又分為以下幾種:
* 數據傳送:movd, movq
* 數據轉換:packsswb, packssdw, packuswb, punpckhbw, punpckhwd, punpckhdq, punpcklbw, punpcklwd, punpckldq
* 并行算術(shù):paddb, paddw, paddd, paddsb, paddsw, paddusb, paddusw, psubb, psubw, psubd, psubsb, psubsw, psubusb, psubusb, psubusw, pmulhw, pmullw, pmaddwd
* 并行比較:pcmpeqb, pcmpeqw, pcmpeqd, pcmpgtb, pcmpgtw, pcmpgtd
* 并行邏輯:pand, pandn, por, pxor
* 移位與旋轉:psllw, pslld, psllq, psrlw, psrld, psrlq, psraw, psrad
* 狀態(tài)管理:emms
這些指令除了需要注意功能外,還需要注意處理的數據類(lèi)型。以上內容為背景介紹,細節請參考手冊。
性能優(yōu)化 ...Performance Optimization
當使用C/C++完成了一個(gè)嵌入式應用的所有功能,性能問(wèn)題常擺在面前, 這時(shí)可以使用profile工具(如gprof)找出產(chǎn)生瓶頸的函數,將這些函數使用匯編徹底重寫(xiě), 例如MPEG-4編解碼器xvid項目 [4]就使用了這種方法, 而且針對不同處理器/指令集分別給出了不同的優(yōu)化,正是如此該項目無(wú)論功能、還是性能均為一流, 顯然這是深度優(yōu)化的目標所在。
在使用流水線(xiàn)、VLIW以及SIMD的體系結構(比如某些 DSP)上, 整個(gè)函數的手工優(yōu)化可以帶來(lái)幾倍到幾十倍的性能提升。 不過(guò),性能允許,對于函數內關(guān)鍵部分使用一些特定的實(shí)現,既突出重點(diǎn)提高性能,又可以盡多地利用C/C++的高級特征, 相對縮短開(kāi)發(fā)周期。 下面給出使用GCC時(shí),應用MMX指令的幾種混合編程方法:
* Intel C/C++ 編譯器intrinsics
* GCC builtin操作
* 嵌入匯編asm construct
Intel C/C++ 編譯器intrinsics ...Intel C/C++ Compiler Intrinsics
查看IA-32 Intel指令集手冊 [2]時(shí),部分指令的解釋中會(huì )有一項“Intel C/C++ Compiler Intrinsic Equivalent”,會(huì )指出該指令對等的intrinsic。 intrinsic在C/C++程序中的語(yǔ)法是以函數形式出現,編譯時(shí)可以直接翻譯為一條MMX指令(復合情況會(huì )生成最直接的幾條), 換言之,如果不使用intrinsic,可能需要多條C/C++語(yǔ)句完成,而編譯器卻并不能保證將這幾條語(yǔ)句能夠生成這條最高效的MMX指令。 并不是每條MMX指令都有對等的intrinsic,手冊的附錄中列出了所有的, 它們分為簡(jiǎn)單型(simple)和復合型(composite)兩種,每個(gè)簡(jiǎn)單型的就是對應一條指令,而復合型則對應多條指令。
GCC支持Intel C/C++ Compiler Intrinsics。用法如下示例:
#include <stdio.h>
#include <xmmintrin.h> /*一定需要包括此頭文件*/
/*gcc -Wall -march=pentium4 -mmmx -o ins  mmx_ins.c*/
int main(int argc,char *argv[])
{
/*使用MMX做以下向量的點(diǎn)積*/
short in1[] = {1, 2, 3, 4};
short in2[] = {2, 3, 4, 5};
int out1;
int out2;
__m64 m1;    /* MMX支持64位整數的mm寄存器 */
__m64 m2;    /* MMX操作需要使用mm寄存器 */
__m128 m128; /* for SSEn only*/
/*每次往mm寄存器裝入兩個(gè)short型的數,注意是兩個(gè)*/
m1 = _mm_cvtsi32_si64(((int*)in1)[0]);
m2 = _mm_cvtsi32_si64(((int*)in2)[0]);
/*一條指令進(jìn)行4個(gè)16位整數的乘加*/
/*生成兩個(gè)32位整數*/
m2  = _mm_madd_pi16(m1, m2);
/*將低32位整數放入通用寄存器*/
out1 =  _mm_cvtsi64_si32(m2);
/*將高32位整數右移后,放入通用寄存器*/
m2  = _mm_slli_pi32(m2, 32);
out2 =  _mm_cvtsi64_si32(m2);
/*清除MMX狀態(tài)*/
_mm_empty();
/*將兩個(gè)32位數相加,結果為8*/
out1 += out2;
printf("a: %d\n", out1);
return(0);
}
幾點(diǎn)說(shuō)明:
* 即使你不是P4平臺,編譯時(shí)也請使用以下選項,
/*gcc -Wall -march=pentium4 -mmmx -o ins mmx_ins.c*/
否則,會(huì )出現如下類(lèi)似信息:
...xmmintrin.h:34:3: #error "SSE instruction set not enabled"
* 最終結果實(shí)際并沒(méi)有求得四對乘積的和,只是前兩對的, instrinsic _mm_cvtsi32_si64只向mm寄存器放入了低32位,高32位為零,但mmx有指令movq可以做到64位的數據傳送,intrinsic沒(méi)有對應, 這也說(shuō)明并不是所有的指令有等價(jià)的intrinsic。
* 當計算的向量為兩對0x8000, 0x8000時(shí),即(-2^15)*(-2^15) + (-2^15)*(-2^15) , 結果應該為 2^31,但計算出來(lái)的值是 -2^31, 因為發(fā)生了溢出,可程序無(wú)從知道。 這是使用MMX時(shí),應特別注意的,計算溢出沒(méi)有任何標志位指示,一個(gè)極大的值變?yōu)闃O小,SSE對此做了改善。
* 程序不再使用MMX之時(shí),注意使用emms指令清除MMX狀態(tài)。
使用built-in操作 ...GCC built-in Operation
什么是built-in操作?就是對待MMX操作數,就如int, float等基本數據類(lèi)型一般, 有相應定義的操作,如加(+)、減(-),或者數據類(lèi)型之間的轉換。 詳細內容參考GNU GCC Manual [5] Extensions to the C Language Family4#4Built-in Functions4#4 X86 Built-in Functions一節。
一些MMX指令有其相應的built-in操作, 下面一段代碼為例:
#include <stdio.h>
/*無(wú)需特別的頭文件,built-in嘛*/
/* gcc -Wall  -o bins  builtinmmx.c*/
/*定義了一個(gè)vector數據類(lèi)型,hi表示16位,4表示4個(gè)*/
typedef int v4hi __attribute__ ((mode(V4HI)));
/*定義了2個(gè)32位的vector類(lèi)型,si表示32位*/
typedef int v2si __attribute__ ((mode(V2SI)));
int main(int argc,char *argv[])
{
short pa[4] = {0x8000, 0x8000, 1, -1};
short pb[4] = {0x8000, 0x7FFF, -1, -2};
v4hi va, vb;
v4hi vsum;
va = ((v4hi*)pa)[0];
vb = ((v4hi*)pb)[0];
/* 4個(gè)16位進(jìn)行飽和加 */
//vsum = __builtin_ia32_paddsw(va, vb);
/* 4個(gè)16位還可以直接進(jìn)行加法,但不同于兩個(gè)long long相加 */
vsum =  va + vb;
/*vector的輸出還需要強制轉換為long long*/
printf("...with MMX instructions...to compute vec_add: %llx \n", (long long)vsum);
//結果1:0xfffd0000ffff8000
//結果2:0xfffd0000ffff0000
return(0);
}
幾點(diǎn)說(shuō)明:
* 是的,這里built-in vector及其操作,隨著(zhù)GCC的發(fā)展正在加強。如果需要使用以上范例,應使用GCC 3.4以上版本;
* 使用builtin函數時(shí),與intrinsic相似;但本質(zhì)卻是不同,這里兩個(gè)向量使用‘+’操作就說(shuō)明了vector也如其它數據類(lèi)型一樣,編譯器直接支持,只不過(guò)這里的加法就是指四個(gè)單元數分別相加,低位單元的進(jìn)位不會(huì )影響相鄰高位單元的數據;
* vector還可以強制轉換為通用數據。
嵌入匯編 ...Inline asm
GCC一開(kāi)始就允許C代碼中嵌入asm指令,并不只是針對MMX指令, 不過(guò)對于MMX技術(shù),顯然也是一個(gè)很好的利用方法, 詳細的語(yǔ)法請參考GNU GCC手冊 [5], 或者GCC: The Complete Reference [6]''''Inline Assembly''''一節。 如下是一個(gè)點(diǎn)積的例子:
#include <stdio.h>
/** GCC -o ins  inlinemmx.c **/
int main(int argc,char *argv[])
{
int i;
int result;
short a[] = {1, 2, 3, 4, 5, 6, 7, 8};
short b[] = {1, 1, 1, 1, 1, 1, 1, 1};
printf("...with MMX instructions...\n");
/*首先,將點(diǎn)積合累積寄存器清零,實(shí)際缺省就為0?*/
asm("pandn %%mm5,%%mm5;"::);
/*讀入a, b,每四對數相乘后分兩組相加,形成兩組和*/
/*這里的循環(huán)控制是C在做*/
for(i = 0; i < sizeof(a)/sizeof(short); i += 4){
asm("movq %0,%%mm0;\
movq %1,%%mm1;\
pmaddwd %%mm1,%%mm0;\
paddd %%mm0,%%mm5; #相乘后相加 "
:
: "m" (a[i]), "m" (b[i]));
}
/*將兩組和分離,并相加*/
asm("movq %%mm5, %%mm0;\
psrlq $32,%%mm5;\
paddd %%mm0, %%mm5;\
movd %%mm5,%0;\
emms"
:"=r" (result)
:);
printf("result: 0x%x\n", result);
//這里結果為0x24
return(0);
}
幾點(diǎn)說(shuō)明:
* 這里是典型的在函數中C和匯編混合編程;
* 注意匯編指令中操作數的順序;
* 這里可以直接使用movq等沒(méi)有intrinsics/built-in對應的指令;
* 注意在asm指令序列中間不要加雜注釋?zhuān)赡軐е律傻拇a不正確。
MMX實(shí)用一例:合成濾波器 ...Synthesis Filter in X86 SIMD INSTRUCTIONS
下面是合成濾波器(Synthesis Filter)的一個(gè)優(yōu)化過(guò)程, 合成濾波器在語(yǔ)音編解碼中有廣泛應用, 運行時(shí)也占用了整個(gè)算法中較高比例的時(shí)間。
for (i = 0; i < lg; i++)
{
s = L_mult(x[i], a[0]);/*L_mult是相乘后左移*/
for (j = 1; j <= M; j++){/*M這里固定為10*/
s = L_msu(s, a[j], yy[-j]);/*L_msu是乘減后左移操作*/
}
s = L_shl(s, 3); /*左移三位*/
*yy++ = g729round(s);
}
#endif
上面的代碼,因為內存循環(huán)為10,可以考慮展開(kāi),并統一操作為乘加指令。
/*為了使用乘加操作,需要調整10個(gè)系數的順序*/
for(i = 0; i < M; i++)
ta[i] = -a[M - i];
ta[11] = 0;
ta[10] = a[0];
for (i = 0; i < lg; i++){
*yy = x[i];
yy[1] = 0;
s = L_mac(s, ta[11], yy[1]);
s = L_mac(s, ta[10], yy[0]);
s = L_mac(s, ta[9], yy[-1]);
s = L_mac(s, ta[8], yy[-2]);
s = L_mac(s, ta[7], yy[-3]);
s = L_mac(s, ta[6], yy[-4]);
s = L_mac(s, ta[5], yy[-5]);
s = L_mac(s, ta[4], yy[-6]);
s = L_mac(s, ta[3], yy[-7]);
s = L_mac(s, ta[2], yy[-8]);
s = L_mac(s, ta[1], yy[-9]);
s = L_mac(s, ta[0], yy[-10]);
s = L_shl(s, 3);
*yy++ = g729round(s);
}
以上循環(huán)內核正好可以將MMX的8個(gè)寄存器全部利用。
/*為了使用乘加操作,需要調整10個(gè)系數的順序*/
for(i = 0; i < M; i++)
ta[i] = -a[M - i];
ta[11] = 0;
ta[10] = a[0];
/*11個(gè)系數分別放入3個(gè)MMX寄存器,0作填充*/
asm("movq %0,%%mm0;\
movq %1,%%mm1;\
movq %2,%%mm2"\
:\
: "m" (ta[0]), "m" (ta[4]), "m"(ta[8]));
/*利用MMX技術(shù)進(jìn)行濾波器核心操作*/
for (i = 0; i < lg; i++){
*yy = x[i];
yy[1] = 0;
asm("pandn %%mm6,%%mm6;\
movq %1,%%mm3;\
movq %2,%%mm4;\
movq %3,%%mm5;\
pmaddwd %%mm0,%%mm3;\
pmaddwd %%mm1,%%mm4;\
pmaddwd %%mm2,%%mm5;\
paddd %%mm3, %%mm6;\
paddd %%mm4, %%mm6;\
paddd %%mm5, %%mm6;\
movq  %%mm6, %%mm7;\
psrlq $32, %%mm6;\
paddd %%mm7, %%mm6;\
movd %%mm6,%0;\
emms"
:
:"r"(s), "m" (yy[-10]), "m" (yy[-6]), "m"(yy[-2]));
/*因為指令結果飽和屬性的限制,s還沒(méi)有左移,所以下面多做一位飽和左移*/
s = L_shl(s, 4);
*yy++ = g729round(s);
}
幾點(diǎn)說(shuō)明:
* 注意:以上嵌入的匯編代碼輸出結果s放在了輸入處,屬于實(shí)踐中的個(gè)案;
* MMX沒(méi)有乘左移之類(lèi)的DSP指令,甚至還沒(méi)有加飽和之類(lèi)的操作,SSE中有一定增強;
* 以上操作,理論上存在溢出可能,所以最后使用原有的飽和左移操作,減少了一定風(fēng)險;
* 上面的部分代碼操作顯然允許并行,這在VLIW系統中十分有用;
* 這已經(jīng)形成了該濾波器全面優(yōu)化的核心。
總結 ...Conclusion
如果愿意盡多地利用SIMD技術(shù),可能需要更多地使用匯編級的編碼, 不過(guò)也有一些高級語(yǔ)言和匯編的混合編程技術(shù)能夠幫助你, 它們有的提高性能更大一些, 有的形式上更優(yōu)雅些,本質(zhì)上效率也不錯, 都不失好的方法,建議嘗試。
正是如此,一方面CPU上支持越來(lái)越多的SIMD指令集擴展, 另一方面GCC也正在加緊支持這些擴展的易用,對,正在, 碰到一些問(wèn)題,先想辦法繞過(guò)去, 這里使用GCC 3.4.1,根據經(jīng)驗效果還是不錯的。
關(guān)于文檔
GCC中SIMD指令的應用方法
This document was generated using the LaTeX2HTML translator Version 2002 (1.62)
Copyright ? 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright ?, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.
The command line arguments were: latex2html -iso_language CN -html_version 4.0,unicode -address ''?2004 CoreUp Designs'' -local_icons -split 0 -nonavigation gccsimd
The translation was initiated by on 2004-12-13
參考資料
1. Intel: IA-32 Intel Architechture Software Developer''s Manual, Volume 1: Basic Architecture(2002)
2. Intel: IA-32 Intel Architechture Software Developer''s Manual, Volume 2: Instruction Set Reference(2003)
3. Intel: IA-32 Intel Architechture Software Developer''s Manual, Volume 3: System Programming Guide(2003)
4. XviD.org,http://www.xvid.org/(up-to-date)
5. GNU, GCC online documentation,http://www.gnu.org/software/GCC/onlinedocs/(up-to-date)
6. Authur Griffith, GCC: The Complete Referencea, McGraw Hill(2002)
關(guān)于作者
錢(qián)浙濱,1999年從上海交通大學(xué)圖像處理與模式識別研究所獲得博士學(xué)位, 曾參與完成計算機視覺(jué)、正規語(yǔ)言和移動(dòng)通信等方面的研發(fā)工作;目前他和他的團隊主要從事DSP系統開(kāi)發(fā),特別是多媒體編解碼算法的性能優(yōu)化, 以及相關(guān)的Linux嵌入式應用;他們也提供WLAN相關(guān)的技術(shù)咨詢(xún), 歡迎訪(fǎng)問(wèn)http://embeddedcore.com進(jìn)行交流。
(編輯:zhou_rm)
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
SIMD函數整理:00 索引貼(2012-07-31更新)
Intrinsics頭文件與SIMD指令集、Visual Studio版本對應表
MMX及SSE優(yōu)化--MMX篇 - 早雪網(wǎng)
核心指令集發(fā)展回顧
CPU指令集的誕生、發(fā)展、分類(lèi)及對處理器性能提升的作用
處理器的大腦 讀懂CPU指令集
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久