If statement 逻辑&;关于OpenCL中的双精度?

If statement 逻辑&;关于OpenCL中的双精度?,if-statement,vector,opencl,bit-manipulation,If Statement,Vector,Opencl,Bit Manipulation,我有两个向量:adouble4*sum和adouble4*elem。我想对向量中的每个元素做如下处理:如果elem是有限的,从sum中减去它,否则什么都不做 目前,我有以下代码: long4 finite = isfinite(elem[e].x); if (finite.x) sum.x-=elem[e].x; if (finite.y) sum.y-=elem[e].y; if (finite.z) sum.z-=elem[e].z; if (finite.w)

我有两个向量:a
double4*sum
和a
double4*elem
。我想对向量中的每个元素做如下处理:如果elem是有限的,从sum中减去它,否则什么都不做

目前,我有以下代码:

   long4 finite = isfinite(elem[e].x);
   if (finite.x) sum.x-=elem[e].x;
   if (finite.y) sum.y-=elem[e].y;
   if (finite.z) sum.z-=elem[e].z;
   if (finite.w) sum.w-=elem[e].w;

然而,这是一堆不必要的
if
语句。它可以被简单的
sum-=isfinite(elem[e])&elem[e]代替,但双打似乎不允许使用&。然而,从硬件技术上讲,它应该是可能的,因为&只是在位级别上。有没有办法模仿这种行为?我应该如何最好地做到这一点呢?

我找到了一个解决方案:显然,
联合会在这方面可以有所帮助

typedef struct {
    union {
        double4 asDouble;
        long4 asLong;
    };
} dubbel;
然后我可以用这个非分支代码替换if语句:

dubbel temp;
temp.asDouble = elem[e];
temp.asLong = temp.asLong & isfinite(temp.asDouble);
sum-=temp.asDouble;
奇怪的是,这在默认情况下并不是作为语法糖提供的,但是,嘿,它可以工作

编辑:正如ScottD在评论中指出的,还有一个更短的解决方案:

sum -= as_double4 (isfinite (elem[e]) & as_long4 (elem[e]));

我找到了一个解决办法:显然,
union
可以帮上忙

typedef struct {
    union {
        double4 asDouble;
        long4 asLong;
    };
} dubbel;
然后我可以用这个非分支代码替换if语句:

dubbel temp;
temp.asDouble = elem[e];
temp.asLong = temp.asLong & isfinite(temp.asDouble);
sum-=temp.asDouble;
奇怪的是,这在默认情况下并不是作为语法糖提供的,但是,嘿,它可以工作

编辑:正如ScottD在评论中指出的,还有一个更短的解决方案:

sum -= as_double4 (isfinite (elem[e]) & as_long4 (elem[e]));

是的,这种方法对我也适用(在AMD和英特尔opencl上测试)。这是另一种变化:
sum-=as_double4(isfinite(elem[e])和as_long4(elem[e])哦,太好了!我不知道那些命令。我会在帖子里加上它们。顺便问一下,你对性能有什么了解吗?我假设在编译后的代码中,两种转换都没有成本,因为它们只是为了让编译器放心?我比较了使用AMD HD 7950生成的代码。union方法和as_uuu_uuuuuuuuuuuu方法的代码是相同的。是的,这种方法对我也适用(在AMD和Intel opencl上测试)。这是另一种变化:
sum-=as_double4(isfinite(elem[e])和as_long4(elem[e])哦,太好了!我不知道那些命令。我会在帖子里加上它们。顺便问一下,你对性能有什么了解吗?我假设在编译后的代码中,两种转换都没有成本,因为它们只是为了让编译器放心?我比较了使用AMD HD 7950生成的代码。联合法和铸态法的代码相同。