OpenCL小于等于和布尔向量

时间:2012-06-16 07:31:26

标签: optimization opencl

我有一种情况,我通过以下方式解决:

//cube_potentials is float8
//level_vec is float8
//shift_vec is int8 and contains (non-overlapping) bit shifts
int8 shifts = (cube_potentials<=level_vec);
int flag_index = 0;\n"
if (shifts.s0) flag_index |= shift_vec.s0;
if (shifts.s1) flag_index |= shift_vec.s1;
if (shifts.s2) flag_index |= shift_vec.s2;
if (shifts.s3) flag_index |= shift_vec.s3;
if (shifts.s4) flag_index |= shift_vec.s4;
if (shifts.s5) flag_index |= shift_vec.s5;
if (shifts.s6) flag_index |= shift_vec.s6;
if (shifts.s7) flag_index |= shift_vec.s7;

有效。问题是所有那些if-statements让我感到烦恼,我无法想象它们也是世界上最快的东西。我想像这样解决它:

//Method 1
bool8 less = (bool8)(cube_potentials<=level_vec);
int8 shifts = (int8)(less) * shift_vec;
int flag_index = shifts.s0 | shifts.s1 | shifts.s2 | shifts.s3 | shifts.s4 | shifts.s5 | shifts.s6 | shifts.s7;

//Method 2 (more simply)
int8 shifts = ((int8)(cube_potentials<=level_vec)) * shift_vec;
int flag_index = shifts.s0 | shifts.s1 | shifts.s2 | shifts.s3 | shifts.s4 | shifts.s5 | shifts.s6 | shifts.s7;

问题是bool8是保留的类型,而不是真正的类型,因此方法1已经用完了。但是,方法2无法正常工作。我怀疑其原因与第一行有关。 &lt; =在两个浮点向量上,我不知道它返回什么,但可能是当它被转换为int8时,它不是全0和1。

我的问题是,是否有办法以更清晰,更平行的方式重写原始代码?

谢谢,

2 个答案:

答案 0 :(得分:3)

试试这个。它可能有用:

// gives -1 (0xFFFFFFFF) or 0 for when T or F for each comparison:
int8 shifts = cube_potentials <= level_vec;

// leaves only the elements that passed the above compare:
shift_vec &= shifts;

// start combining (with all 8 elements):
shift_vec.lo |= shift_vec.hi;

// keep going (down to the bottom 4):
shift_vec.lo.lo |= shift_vec.lo.hi;

// last one (only considering the bottom two):
int flag_index = shift_vec.lo.lo.lo |= shift_vec.lo.lo.hi;

答案 1 :(得分:0)

编辑:好的,第二次尝试:

flag_index = dot(shift_vecs, -islessequal(cube_potentials, level_vec));

我想要围绕这一点做出好评。

  • islessequal()应返回-1或0表示true和false。
  • 我们否定它得到1或0
  • 然后我们使用点积来汇总shift_vecs中返回true的组件。

注意:

  • dot()通常是硬件指令,所以应该很快。
  • islessequal()可以替换为<=
  • 仅当shift_vec位值由于使用求和而不重叠(您说它们是)时才有效。