正如评论中指出的那样,这不是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