0

次の方法で解決した状況があります。

//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 ステートメントが私をいらいらさせることであり、それらが世界で最も速いものであるとは想像もできません。私はそれを次のように解決したかった:

//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 は正しく機能しません。その理由は最初の行に関係していると思います。<= は 2 つの浮動小数点ベクトル上にあり、それが何を返すかはわかりませんが、おそらく int8 にキャストされると、すべてが 0 と 1 になるわけではありません。

私の質問は、元のコードをよりクリーンで並列な方法で書き直す方法があるかどうかです。

ありがとう、

4

2 に答える 2

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;
于 2012-06-16T21:45:30.950 に答える
0

編集:わかりました、2回目の試み:

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

それについては良いコメントが欲しいのですが。

  • islessequal()true と false に対して -1 または 0 を返す必要があります。
  • 1または0を得るためにそれを否定します
  • 次に、内積を使用して、true を返した shift_vecs のコンポーネントを合計します。

ノート:

  • dot() は多くの場合ハードウェア命令であるため、高速である必要があります。
  • islessequal()で置き換えることができます<=
  • shift_vec合計を使用しているため、ビット値が重複していない(重複していると言った)場合にのみ機能します。
于 2012-06-18T08:43:25.430 に答える