这个article讨论了代码的优化,并讨论了指令级并行性。他们举了一个GPU矢量数学的例子,其中float4矢量数学可以在矢量而不是单个标量上执行。给出的例子:
float4 x_neighbor = center.xyxy + float4(-1.0f, 0.0f, 1.0f, 0.0f);
现在我的问题是它是否可以用于比较目的?所以在缩减示例中,我可以这样做:
accumulator.xyz = (accumulator.xyz < element.xyz) ? accumulator.xyz : element.xyz;
谢谢。
答案 0 :(得分:5)
正如Austin所述,比较运算符也适用于向量。
d点。在标准6.3节中是您的相关部分。它说:
关系运算符大于(&gt;),小于(&lt;),大于 等于(&gt; =),小于或等于(&lt; =)对标量和 矢量类型。
它也解释了有效案例:
这两个操作数是标量。 (...)
一个操作数是标量,另一个是矢量。 (...)然后将标量类型扩展为具有相同数量的向量 组件作为向量操作数。操作是按组件完成的 产生相同大小的矢量。
两个操作数是相同类型的向量。在这种情况下,操作以分量方式完成,从而产生相同大小的矢量。
最后,这些比较运算符会返回:
如果是源,则结果是int类型的标量有符号整数 操作数是标量和相同大小的向量有符号整数类型 如果源操作数是矢量类型,则作为源操作数。
对于标量类型,关系运算符如果是,则返回0 指定的关系为false,如果指定的关系为true,则为1。 对于向量类型,如果是,则关系运算符应返回0 指定的关系是假和-1(即所有位设置),如果 指定的关系是真的。关系运算符总是返回0 如果任一参数不是数字(NaN)。
修改强>
要完成一点返回值部分,特别是在@ redrum的评论之后;一开始看起来很奇怪,矢量类型的真值是-1。但是,由于OCL像C一样尽可能地表现,因为不同于0的所有内容都是真的,所以它不会发生很大的变化。
例如,你有矢量:
int2 vect = (int2)(0, -1);
此声明将评估为true并执行某些操作:
if(vect.y){
//Do something
}
现在,请注意这是无效的(与返回的值无关,但仅与它是矢量有关):
if(vect){
//do something
}
这不会编译,但是,您可以使用函数all
和any
来评估“if语句”中向量的所有元素:
if(any(vect){
//this will evaluate to true in our example
}
请注意,返回的值是(来自快速参考卡):
int any (Ti x): 1 if MSB in component of x is set; else 0
所以任何负数都可以。
但是,为什么在评估为true时不保留1作为返回值?
我认为重要的部分是所有位都已设置的事实。我的猜测是,就像你可以在向量上轻松按位运算一样,比如你想要消除小于给定值的元素。由于值“true”为-1,即111111 ... 111,你可以做类似的事情:
int4 vect = (int4)(75, 3, 42, 105);
int ref = 50;
int4 result = (vect < ref) & vect;
和结果的元素将是:0,3,42,0
另一方面,如果返回值为1表示为true,则结果为:0,1,0,0答案 1 :(得分:1)
OpenCL 1.2 Reference Card from Khronos表示逻辑运算符:
运营商[6.3] 除了之外,这些运算符的行为与C99类似 操作数可能包括可能的向量类型: + - *%/ - ++ ==!=&amp; 〜^&gt; &LT; &gt; =&lt; = | ! &安培;&安培; || ?:&gt;&gt; &LT;&LT; =,op = sizeof