OpenCL - GPU矢量数学(指令级并行)

时间:2013-08-30 14:02:26

标签: parallel-processing opencl gpu

这个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;

谢谢。

2 个答案:

答案 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
}

这不会编译,但是,您可以使用函数allany来评估“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