正如評論中指出的那樣,這不是OpenCL代碼。然而,如果您的意思是如何將此代碼轉換爲 OpenCL,則矢量化的方法是使用矢量類型,例如float4(四個32位浮點數),double3(三個64位雙精度),long8(八個64比特整數)等等......甚至還有內置像四核(128位浮點),複雜雙打等硬核類型......
在你的情況下,你基本上想要的是解開一堆字節轉換爲16位字,分離輸入的低四元組和高四元組。你可以通過swizzling或明確計算每個向量來做到這一點,但也有另一種方法來做這個特定的計算 - OpenCL有一個向量分裂機制,它將任意向量類型分成兩個更低和更高的一半。這是這樣完成的:
float4 input = (float4)(4.3, 0.71, 9.1, 44.8);
float2 inputLo = input.lo; // = (4.3, 0.71)
float2 inputHi = input.hi; // = (9.1, 44.8)
顯然,這是適合於您的問題,因爲所有你需要做的就是你的char16(16個8位字節)分成兩個較低和較高CHAR8的,並解釋這些CHAR8的作爲short8's(因爲你是解包),無論是通過投射或明確轉換。
請注意,這對於OpenCL來說是一個奇怪的問題 - 這種解包機制來自數據必須打包到SSE寄存器的方式,所以如果你想從8位元素切換到16位。在OpenCL中,這是沒有必要的,因爲您的矢量類型不承擔特定的數據安排(並且您可以很容易地從一種類型轉換爲另一種類型)。如果您的OpenCL內核恰好在支持SSE的處理器上執行,那麼內核編譯器會自動爲您打包和解包 - 希望最佳,如果您的代碼是理性的。
您不能在OpenCL中使用內部函數,因爲內核不會在x86和x64硬件上獨佔運行 - 它們也可以在GPU,FPGA和定製芯片上運行。相反,您使用的通用矢量類型會自動轉換爲編譯內核的平臺上正確的SIMD指令(實際上,它稍微複雜一點,但這是它的要點)。
鑑於您的最新評論,我會補充一點:如果你想在內部函數轉化爲簡單的C代碼,所有需要的是數據是如何打包到SSE寄存器的理解。從基本的角度來看,它是如何工作的:每個SSE寄存器都是128位寬,因此可以保存16個字節,8個字,4個長等等......你不能混合這些類型,所以你不能2個字節和7個字,每個內在函數都假設一個特定的類型(例如,您可能想要寄存器中每個64位雙精度的平方根,或每個32位浮點數的平方根!清楚表明您選擇哪種類型) 。
這些類型總是連續的,所以說你想將一個8字的向量轉換成兩個4字長的向量,即「解包」它可以對其進行32位計算,這意味着你想要從去:
[16-bit][16-bit][16-bit][16-bit][16-bit][16-bit][16-bit][16-bit]
到
[32-bit][32-bit][32-bit][32-bit] & [32-bit][32-bit][32-bit][32-bit]
顯然你不能只重用寄存器,因爲兩個16位字將得到合併成一個單一的32位的值,它會產生垃圾。相反,您必須有條不紊地將每個16位字拉出來,將其轉換爲32位長,並將其放入新寄存器--SSE在硬件中執行所有操作(內部調用適當的指令)。
在您的具體情況下,您有一個包含16個字節的寄存器,並且您希望將數據「輸出」到另外兩個寄存器中,而這些寄存器將包含8個字。所以,如果你輸入寄存器包含a0..a15(這些都是字節),那麼你將有:
b0 = (word)a_0..(word)a_7
b1 = (word)a_8..(word)a_15
您可以在C使用數組做到這一點,「模擬」的SSE寄存器(你可以做花哨包含每個可能的矢量的聯合,這個聯合適合於一個寄存器,或者只是硬編碼不同的數組類型並相互轉換)。
僅供參考,請參閱this,它對此有所解釋(我也建議您閱讀SSE寄存器如何工作,因爲這是包裝存在的原因以及它的重要性)。
該代碼不是OpenCL它**是具有x86 SSE2整數內部指令的**標準C. – talonmies 2012-08-08 06:31:36
是啊,對不起,我的意圖是將該代碼轉換爲OpenCL,但之前轉換爲C lang。,所以..我誤以爲thomas爲您的答覆 – Fakruddeen 2012-08-08 09:00:55