在C/C++代码中使用SSE等指令集的指令(1)介绍
我們知道,在C/C++代碼中,可以插入?yún)R編代碼提高性能。現(xiàn)在的指令集有了很多的高級指令,如果我們希望使用這些高級指令來實現(xiàn)一些高效的算法,就可以在代碼中嵌入?yún)R編,使用SSE等高級指令,這是可行的,但是如果對匯編不太熟悉,不愿意使用匯編的人來說,其實也是可以的,這就是Compiler Intrinsics(http://msdn.microsoft.com/zh-cn/site/26td21ds)。
PS:下面的內(nèi)容以Windows平臺為主,對于Linux下,也有類似的方法。
(1)什么是Intrinsics
Intrinsics是對MMX、SSE等指令集的指令的一種封裝,以函數(shù)的形式提供,使得程序員更容易編寫和使用這些高級指令,在編譯的時候,這些函數(shù)會被內(nèi)聯(lián)為匯編,不會產(chǎn)生函數(shù)調(diào)用的開銷。在理解intrinsics指令之前,先理解intrinsics函數(shù)。
(3)#pragma intrinsic和#pragma function
#pragma intrinsic(function[,function][,function]...):表示后面的函數(shù)將進行intrinsic,替換為內(nèi)部函數(shù),去掉了函數(shù)調(diào)用的開銷,注意:有些地方解釋為內(nèi)聯(lián),但是和內(nèi)聯(lián)并不完全相同,對于內(nèi)聯(lián),可以指定任意函數(shù)為內(nèi)聯(lián),但是此pragma intrinsic只能適用于編譯器規(guī)定的一部分函數(shù),不是所有函數(shù)都能使用,而且,inline關鍵字一般用于指定自定義的函數(shù),intrinsic則是系統(tǒng)庫函數(shù)的一部分。參考http://technet.microsoft.com/zh-cn/library/tzkfha43.aspx獲取詳細的說明。
下面分析這個例子:
cl /c test.c /FA
輸出得到其匯編文件:
仍然參考MSDN(http://technet.microsoft.com/zh-cn/library/tzkfha43.aspx)可以看到其中一段話:
The floating-point functions listed below do not have true intrinsic forms. Instead they have versions that?pass arguments directly to the floating-point chip rather than pushing them onto the program stack.
當然,這是描述其中一部分Intrinsics函數(shù)的,Intrinsics也有不同的方式進行優(yōu)化/內(nèi)聯(lián),具體參考MSDN查詢哪些函數(shù)可以使用Intrinsics以及是如何工作的(http://msdn.microsoft.com/zh-cn/site/26td21ds)。
#pragma function:使用格式和intrinsics一樣,pragma function用于指定函數(shù)不進行intrinsics操作,也就是不生成內(nèi)部函數(shù)。
最后,要知道的一個內(nèi)容是一個相關的編譯選項:/Oi
http://technet.microsoft.com/zh-cn/library/f99tchzc.aspx
/Oi 僅作為對編譯器的請求,用于將某些函數(shù)調(diào)用替換為內(nèi)部函數(shù);為產(chǎn)生更好的性能,編譯器可能會調(diào)用函數(shù)(而不會將該函數(shù)調(diào)用替換為內(nèi)部函數(shù))。
簡單的理解,就是告訴編譯器盡量使用intrinsics版本的調(diào)用,當然,最終的實際調(diào)用依賴于編譯器的判斷。
也可以參考wiki中(http://en.wikipedia.org/wiki/Intrinsic_function)關于intrinsic functions來幫助理解其作用。簡單來說,可以理解為編譯器的“內(nèi)置函數(shù)”,編譯器會根據(jù)情況進行一些優(yōu)化。
(4)指令集相關的intrinsics介紹
上面介紹的是pragma對intrinsic函數(shù)的使用,其中介紹了cos,還有很多類似的“內(nèi)置函數(shù)版本”。有時候?qū)⑸厦娴倪@些稱之為”intrinsics函數(shù)“,除此之外,intrinsics更廣泛的使用是指令集的封裝,能直接映射到高級指令集,從而使得程序員可以以函數(shù)調(diào)用的方式來實現(xiàn)匯編能達到的功能,編譯器會生成為對應的SSE等指令集匯編。
1. 如何使用這類函數(shù)
在windows上,包含#include <**mmintrin.h>頭文件即可(不同的指令集擴展的函數(shù)可能前綴不一樣),也可以直接包含#include <intrin.h>(這里面會根據(jù)使用環(huán)境判斷使用ADM的一些兼容擴展)。
2.?關于數(shù)據(jù)類型
這些和指令集相關的函數(shù),一般都有自己的數(shù)據(jù)類型,不能使用一般的數(shù)據(jù)類型傳遞進行計算,一般來說,MMX指令是__m64(http://msdn.microsoft.com/zh-cn/library/08x3t697(v=VS.90).aspx)類型的數(shù)據(jù),SSE是__m128類型的數(shù)據(jù)等等。
3. 函數(shù)名:
這類函數(shù)名一般以__m開頭。函數(shù)名稱和指令名稱有一定的關系。
4. 加法實例:
下面使用SSE指令集進行加法運算,一條指令對四個浮點數(shù)進行運算:
(5)總結:
1.?Intrinsics函數(shù):能提高性能,會增大生成代碼的大小,是編譯器的”內(nèi)置函數(shù)“。
2. Intrinsics對指令的封裝函數(shù):直接映射到匯編指令,能簡化匯編代碼的編寫,另外,隱藏了寄存器分配和調(diào)度等。由于涉及到的數(shù)據(jù)類型、函數(shù)等內(nèi)容較多,這里只是一個簡單的介紹。
總結
以上是生活随笔為你收集整理的在C/C++代码中使用SSE等指令集的指令(1)介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全款压尾款是什么意思
- 下一篇: 阴阳师手游2021SP姑获鸟阵容怎么搭配