OpenCL 整数函数

本文介绍了OpenCL中的整数运算,包括加法和减法函数如add_sat和sub_sat,乘法运算如mul_hi、mul24以及mad系列函数。特别关注了算术溢出问题,如加法和乘法可能导致的溢出,并解释了饱和计算如何处理这种情况。此外,还探讨了旋转和上采样等其他整数函数的特性和使用场景。

1.整数函数分为三类来讨论;加法运算和减法运算,乘法运算,以及其余类型的函数。在各种整数函数的运算中,integer数据类型指代范围包含有符号整数和无符号整数:uchar,char,ushort,short,uint,int,ulong和long.uinteger型指代范围仅仅是无符号整数:uchar,ushort,uint和ulong.

2.加法和减法函数:

1)integern add_sat(integern x,integern y)--返回的x+y,饱和结果;
(2)integern hadd(integern x, integern y)--返回的x+y,结果右移一位,防止溢出;
(3)integern rhadd(integern x,integern y)--返回x+y+1,结果右移一位,防止溢出;
(4)integern sub_sat(integern x,integern y)--返回x-y,饱和结果。

考虑的问题:计算结果占用的空间大于操作数所占的空间,这种情况也被称为算数溢出。
如果对两个有符号正整数求和,结果大于最大值时,溢出的发生将会导致返回值为负值。但是add_sat和sub_sat这两个函数会在上溢出发生时,将饱和结果返回,也就是直接返回所能表示的最大值。以32位int型为例,最大值返回将是0x7FFFFFFF.

3.乘法运算:整数相乘所得到的结果也会比操作数需要更多的存储空间,最差的情况就是乘积所要的空间是操作数的两倍。

1)integern mad_hi(integern a,integern b, integern c)--返回mul_hi(a,b)+c;2)integern mad_sad(integern a,integern b, integern c)--返回a*b+c,饱和结果;
(3)integern mad24(u/intn a,u/intn b, u/intn c)--返回mul24(a,b)+c;4)integern mul_hi(integern x, integern y)--计算x*y,返回结果的后半部分;
(5)u/intn mul24(u/intn x, u/intn y)--对x和y的低24位求积。

mul_hi函数将返回乘积的高位部分,而操作符*将返回乘积的低位部分。例;
假设x等于0x71111111,y等于0x72222222,他们相乘的正确结果应是0x3268ACF11ECA8642.但是如果你要用OpenCL计算得到这样的结果,就需要下面的操作:

1mul_hi(x,y)=0x3268ACF1;2)x*y = 0xECA8642;

当速度优先于精度时,Mul24函数非常有用。但是它只能对int型和uint型数据进行操作,并且只能是操作数的低24位。因此,如果两个操作数x和y都是int型,其值应当在-2的23次方和2的23次方-1的示数范围之内。而如果x和y都是uint型,那么他们的值就应当在0和2的24次方-1之间。

和操作符一样,mul24函数将只返回乘积的低32位。和操作符的区别仅仅是在于函数的计算速度更快,因为mul24只考虑操作数的低24位。例如,x和y都是int型变量,其中x等于0x00711111,而y等于0x00722222,那么,所得到的乘积将是0x3268ACDA8642,需要46位来存储。而Mul24(x,y)的返回值将是0xACDA8642.

mad_sat函数需要用到操作符“*”,并在结果上溢出时,饱和结果返回。mad_hi函数在计算乘积的高位部分时,调用的是mul_hi函数,而在对第三个参数的求和运算时,是直接返回,不做处理。和mad_hi函数类似,但mad24函数在计算乘积的低位部分时,调用的是mul24函数。

mad_hi函数返回结果的高位部分,而mad函数返回结果的低位部分。两相互补,得到正确结果。mad_sat并没有上下两部分的概念,他会假设是在进行整体计算,所以如果结果大于所能保存的最大值时,它会产生溢出。

4.其他类型的整数函数:

1)uintegern abs(integern x)--返回x的绝对值,|x|2)uintegern abs_diff(integern x,integern y)--返回x-y的绝对值,|x-y|3)integern clamp(integern x, integer/n min, integer/n max)--返回min如果x<min;返回max,如果x>max,否则返回x.4)integern max(integern x, integern y)--如果x>=y,返回x,否则返回y;5)integern min(integern x, integern y)--如果x>y,返回y,否则返回x;6)integern rotate(integern x, integern y)--将x中的每个元素左移,其位数就是y中对应元素的取值,左侧移出的位数再从右侧移入;
(7)u/shortn upsample(u/charn high, ucharn  low)--通过将high和low的分量拼接,得到u/short返回值;
(8)u/intn upsample(u/shortn high, ushortn low)-- 通过将high和low的分量拼接,得到u/int返回值;
(9)u/longn upsample(u/intn high,uintn low)--通过将high和low的分量拼接,得到u/long返回值。

如果x是uchar型变量,其取值为252(11111100),rotate(x,3)的结果为224(11100000),这和x<<3的结果相同。但如果x是有符号char型变量,等于-4(11111100),rotate(x,3)将返回-25(11100111),而x<<3的结果为-32(11100000).
upsample函数会将输入参数拼接,得到两倍于输入参数的结果。如果第一个参数是有符号型整数,结果也将是有符号型整数。第二个输入参数必须一直为无符号型整数。

1)如果x是char型变量,取值为0x95,y是char型变量,取值为0x31upsample(x, y)返回的是short型变量,取值为0x9531;2)如果x是ushort型变量,取值为0x7654,y是uchar型变量,取值为0x3210upsample(x,y)返回的是uint型变量,取值为0x76543210;3)如果x是uint型变量,取值为0x79ABCDEF,y是uint型变量,取值为0x12345678, upsample(x,y)返回的是ulong型变量,取值为-ox79ABCDEF12345678(如果设备支持64位浮点是的话)

upsample函数并不是通过其他向量来创建向量的唯一方法。使用mask向量,也可以使用混洗和选择函数来选择应该将那些输入位或输入分量作为输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值