您的位置:首页 > 运维架构

opencl:kernel中两种向量类型转换(convert_T,as_typen)的主要区别

2016-04-17 10:53 911 查看
熟悉C语言的开发者都知道,一般我们在C中,强制类型转换用()就可以了,比如将一个
int
转换为
float
:

int i=4;
float f=(float)i;


在opencl中对于标量类型(scala data types),上面的语法规则也一样通用,但是对于向量类型(vector data types)的数据,就不可以用上面这种简单的方式进行强制类型转换。

opencl kernel中向量类型转换分为两种方式,explicit conversionsreinterpreting type,中文可以分别直译为”显式转换”和”重新解释类型”。本文讨论这两种类型转换的区别。

explicit conversions

“显式转换”函数的原形描述如下

convert_destType(sourceType)
destType convert_destType<_sat><roundingMode> (sourceType)
destTypen convert_destTypen<_sat><roundingMode> (sourceType)


“显式转换”方式可以将源向量类型转换为元素类型长度不同的目标向量类型,这种转换后的目标向量类型的数据与原数据相比可能是被修改过的,比如:

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

“重新解释类型”函数的原形如下:

as_type(sourceType)// 用于标量类型
as_typen(sourceTypen) //用于向量类型


“重新解释类型”方式的类型转换则是在不修改原数据类型内容的情况下将源数据类型解释为另外一种类型

比如:

float f=as_float(0x3f800000);
//将一个4字节的整型数字0x3f800000转为float,这个float的值是1.0f
//转换后的float还是4字节,并且所有的bit值没有任何变化


这种方式的转换要求源数据类型的总长度与目标类型的总长度必须是一致的。

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()》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息