Double 带有双参数的OpenCL select()函数

Double 带有双参数的OpenCL select()函数,double,opencl,simd,Double,Opencl,Simd,我正在将一些复杂的工程代码移植到OpenCL,但在使用带双精度的select三元函数时遇到了问题。我现在只使用标量,所以我可以使用简单的C三元运算符?:但我计划很快转向向量类型 我的问题是select with doubles需要一个长类型作为比较,但是标量关系函数(例如isgreater)只返回int作为doubles。这些功能的原型是 int isgreater (double a, double b); longn isgreater (doublen a, doublen b);

我正在将一些复杂的工程代码移植到OpenCL,但在使用带双精度的select三元函数时遇到了问题。我现在只使用标量,所以我可以使用简单的C三元运算符?:但我计划很快转向向量类型

我的问题是select with doubles需要一个长类型作为比较,但是标量关系函数(例如isgreater)只返回int作为doubles。这些功能的原型是

int   isgreater (double a, double b);
longn isgreater (doublen a, doublen b);

double  select (double a, double b, long cmp);
doublen select (doublen a, doublen b, longn cmp);
只有在强制转换isgreater的结果时,我才能在标量模式下编译/运行标量代码,因为select要求元素类型的大小相同

double hi = ...;
double lo = ...;
double res = select (lo, hi, (long)isgreater(T, T_cutoff));
否则,我会得到一个编译器错误,因为select是不明确的。关于标量和向量双精度的关系掩码类型,规范中似乎存在不匹配

问题1:这是规范中的疏忽还是实现中的缺陷?英特尔和AMD OpenCL编译器在CPU上的构建都失败了,所以我猜是前者

Q2:OpenCL标量关系函数返回0/1,向量关系函数返回0/-1,即所有位集。int->long转换似乎与此要求一致,但不是int->ulong,对吗?int->long转换代价高吗

问题3:如果我切换到向量双精度,编译器会放弃不必要的显式转换吗?我想保留标量和向量类型,这样我就可以针对CUDA GPU和SIMD设备MIC,CPU必须保留两个大量的代码集

谢谢您的建议。

Q1: 我想说,没有隐式地将isgreer的结果转换为long是规范中的一个疏忽

在单元素情况下,select的工作方式应与三元运算符完全相同。这也是在标量情况下ismorer返回1的原因。基本上,当使用标量运算符时,isgreater应该像>一样工作

在矢量化的情况下,select查看MSB,这就是isgreater返回-1所有位1的原因,因此MSB自然也是1

问题2:Int-long转换应该一点也不昂贵。最多只需要一条附加指令

问题3: 事实并非如此


这个问题令人恼火,它阻止人们编写一个从1到n个元素的矢量化代码,它需要对标量情况进行特殊处理。

在我看来,isgreaterT>T\u截断应该是isgreaterT,T\u截断。这是打字错误吗?有一样东西你可以用。如果您编写的代码可以简单地将double替换为double2,那么就可以将long替换为long2等。我忘记在回答中提到这一点了。谢谢sharpneli。我现在用double2到double16和long2到long16来处理向量问题。最后,我不得不使用一个ifdef语句来处理标量情况,即cast isbetter to long,这非常烦人。我将请求OpenCL2.0规范的功能更新,以支持隐式强制转换,以支持标量isbether情况下的long和/或在选择函数比较中支持int。我更喜欢后者,因为它与常见的c99比较函数相匹配。