1

本文讨论代码的优化并讨论指令级并行性。他们给出了一个 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;

谢谢你。

4

2 回答 2

5

正如奥斯汀已经说过的,比较运算符也适用于向量。

点 d。在标准的第 6.3 节中是与您相关的部分。它说:

大于 (>)、小于 (<)、大于等于 (>=) 和小于等于 (<=) 的关系运算符对标量和向量类型进行操作。

它还解释了有效案例:

  • 这两个操作数是标量。(...)

  • 一个操作数是标量,另一个是向量。(...) 然后将标量类型扩展为具有与向量操作数相同数量的分量的向量。该操作是按组件完成的,导致相同大小的向量。

  • 这两个操作数是相同类型的向量。在这种情况下,操作是按组件完成的,从而产生相同大小的向量。

最后,这些比较运算符返回什么:

如果源操作数是标量,则结果是 int 类型的标量有符号整数;如果源操作数是向量类型,则结果是与源操作数大小相同的向量有符号整数类型。

对于标量类型,如果指定的关系为假,则关系运算符应返回 0,如果指定的关系为真,则应返回 1。对于向量类型,如果指定关系为假,关系运算符应返回 0,如果指定关系为真,则返回 –1(即所有位设置)。如果任一参数不是数字 (NaN),则关系运算符始终返回 0。

编辑:

完成一点返回值部分,尤其是在@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 为真,则结果为:0, 1, 0, 0

于 2013-08-31T07:59:20.477 回答
1

Khronos的OpenCL 1.2 参考卡说逻辑运算符:

运算符 [6.3] 这些运算符的行为与 C99 中的类似,只是操作数可能包含向量类型: + - * % / -- ++ == != & ~ ^ > < >= <= | !&& || ?: >> << = , op= sizeof

于 2013-08-30T18:38:01.490 回答