【问题标题】:NEON pack vector compare result into bitmapNEON 包矢量比较结果成位图
【发布时间】:2018-03-16 02:11:07
【问题描述】:

我有一个比较两个浮点操作数的比较结果如下;我需要做的是根据比较结果需要执行以下操作:即:

neon_gt_res = vcgtq_f32(temp1, temp2);
if(neon_gt_res[0]) array[0] |= (unsigned char)0x01;
if(neon_gt_res[1]) array[0] |= (unsigned char)0x02;
if(neon_gt_res[2]) array[0] |= (unsigned char)0x04;
if(neon_gt_res[3]) array[0] |= (unsigned char)0x08;

但是这样写又等同于多重比较。如何以最佳方式在 neon C 内在函数中编写此代码。

在 x86 上,这将是 array[0] |= _mm_movemask_ps(cmp_gt_res);

【问题讨论】:

  • array[] 是什么类型?我假设它是一个字节数组,但你的 C 有点暗示。您需要一个 1 2 4 8 的向量,并用比较结果对其进行掩码。但是我认为,您需要一个洗牌将结果打包到 NEON 寄存器的低 4 个字节中。我不太了解 NEON,但如果你能做到这一点,你可能会想要对数组进行 32 位加载,进行打包 OR,然后存储。
  • array[] 是无符号字符类型。比较结果是 int32x4_t 类型,因此我不能使用该掩码。有没有其他方法可以帮助我解决这个问题
  • 但是 NEON 没有任何字节洗牌指令可以用来从比较结果的每个元素中打包 1 个字节吗?
  • 我不知道该怎么做;该结果向量中的每个通道都是 4 个字节。太多的拆包不会有利于霓虹灯优化。
  • neon_gt_result &= (appropriate_vectype){1,2,4,8}; neon_gt_result2 = vpadd_appropriate_size(neon_gt_result); neon_gt_result3 = vpadd_twice_appropriate_size(neon_gt_result2); appropriate_read_modify_write_sequence(neon_gt_result3, array); 这是两个额外的 vpadd() 指令和一个位与除了你的比较。我会说这很好,我会更担心内存交互。

标签: c arm intrinsics neon


【解决方案1】:
vmov.i32 qmask, #1
vand qres, qmask, qres
vsra.u64 qres, qres, #30
vsli.64 dres_bottom, dres_top, #2

并且您在 qres 的四个最低有效位上拥有所需的位。

/////////////////////编辑

上面的改进版本:

vshr.u64 qres, qres, #31
vsli.64 dres_bot, dres_top, #2
// the four LSBs already contain the bitmap, the rest is optional:
vbic.i16 dres_bot, #0xf0
// you can now use byte 0 of dres_bot as the result.

【讨论】:

  • 与打包 two 比较结果为 8 位位图(如果先用 &1 屏蔽它们):stackoverflow.com/questions/49506114/…
  • aarch64 怎么样?在 aarch64 v 寄存器中没有重叠的 d 寄存器
  • @daquexian 在这种情况下,您只需使用 {1, 2, 4, 8} 和 addv 执行 and。
猜你喜欢
  • 2012-02-22
  • 2015-06-26
  • 2011-11-24
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
相关资源
最近更新 更多