版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433756
熟悉C语言的开发者都知道,一般我们在C中,强制类型转换用()就可以了,比如将一个int
转换为float
:
int i=4;
float f=(float)i;
在opencl中对于标量类型(scala data types),上面的语法规则也一样通用,但是对于向量类型(vector data types)的数据,就不可以用上面这种简单的方式进行强制类型转换。
opencl kernel中向量类型转换分为两种方式,explicit conversions和reinterpreting type,中文可以分别直译为”显式转换”和”重新解释类型”。本文讨论这两种类型转换的区别。
explicit conversions
“显式转换”函数的原形描述如下
代码语言:javascript复制convert_destType(sourceType)
destType convert_destType<_sat><roundingMode> (sourceType)
destTypen convert_destTypen<_sat><roundingMode> (sourceType)
“显式转换”方式可以将源向量类型转换为元素类型长度不同的目标向量类型,这种转换后的目标向量类型的数据与原数据相比可能是被修改过的,比如:
代码语言:javascript复制char2 c=(short2)(0x02,0x04);
int2 i=convert_int2(c);
// i内容为(0x00000002,0x00000004);与原数据相比,向量元素类型数据长度从1个字节扩展成了4个字节
对于向量类型来说,”显式转换”方式要求就是源类型和目标类型的元素个数必须是一样的,就是说,不允许将int4
用convert_int2
或convert_float2
转换为int2
或float2
。
关于explicit conversions更详细的说明参见《opencl官网文档 Explicit conversions with convert_T()》
reinterpreting type
“重新解释类型”函数的原形如下:
代码语言:javascript复制as_type(sourceType)// 用于标量类型
as_typen(sourceTypen) //用于向量类型
“重新解释类型”方式的类型转换则是在不修改原数据类型内容的情况下将源数据类型解释为另外一种类型
比如:
代码语言:javascript复制float f=as_float(0x3f800000);
//将一个4字节的整型数字0x3f800000转为float,这个float的值是1.0f
//转换后的float还是4字节,并且所有的bit值没有任何变化
这种方式的转换要求源数据类型的总长度与目标类型的总长度必须是一致的。
代码语言:javascript复制float f = 1.0f;
uint u = as_uint(f); // 合法. u为: 0x3f800000
float4 f = (float4)(1.0f, 2.0f, 3.0f, 4.0f);
// 合法. i为: (int4)(0x3f800000, 0x40000000, 0x40400000, 0x40800000)
int4 i = as_int4(f);
float4 f, g;
int4 is_less = f < g;
// 合法. f[i] = f[i] < g[i] ? f[i] : 0.0f
f = as_float4(as_int4(f) & is_less);
int4 i;
// 合法. int4为16字节 short8也是16字节
short8 j = as_short8(i);
float4 f;
//错误. double4(32字节)与float4(16字节)长度不同
double4 g = as_double4(f);
float4 f;
// 合法. 因为float4和float3其实都是32字节长度
float3 g = as_float3(f);
关于reinterpreting type更详细的说明参见《opencl官网文档 Reinterpreting Types Using as_type() and as_typen()》