【问题标题】:Copy low 64-bits to high 64-bits using int64x2_t vector?使用 int64x2_t 向量将低 64 位复制到高 64 位?
【发布时间】:2016-09-05 11:35:07
【问题描述】:

我很难找到我需要的 NEON 内在。我有一个 128 位值作为 int64x2_t,我需要将低 64 位复制到高 64 位。有时我还需要将高 64 位复制到低 64 位。

NEON 有一个lane dup,但它接受int64x1_t 并返回一个int64x1_t

int64x1_t   vdup_lane_s64(int64x1_t vec, __constrange(0,0) int lane);

范围也似乎不正确,因为我似乎应该能够选择 1 或 2。(也许这是我的误解)。

如何将int64x2_t 中的低 64 位复制到高 64 位?


我没有使用下面建议的(high >> x) | (low << x) 模式。首先,它的undefined behavior in C/C++ when x is 0。其次,值 应该 在 NEON SIMD 寄存器中,所以我不想意外往返。第三,GCC is not generating the code I hoped for,所以我不想给 GCC 慢下来的机会。

【问题讨论】:

  • 您将如何使用任何标准类型来做到这一点?假设你想交换一个 32 位整数的高 16 位和低 16 位,你会怎么做?你会使用什么按位运算? int64x2_tint64x1_t 是否有类似的内在函数?
  • int64x2_t vdupq_n_s64(int64_t value); // VMOV d0,r0,r0
  • @JoachimPileborg - 在 C 中使用带有 int64x2_t(实际上是指针)和类似 vdup_lane_s64 的函数的 bitops,我将执行强制转换以消除编译器错误。我不清楚在这里做是否安全。因此,我正在寻找“NEON 方式”做事的原因。
  • 无论类型如何,您都会使用(high >> x) | (low << x)
  • @Lundin - 如果我的变量在 SIMD 寄存器中,那么我可能应该使用内部函数来确保它不会从 SIMD 协处理器移动到通用寄存器以进行移位。这是我正在寻找与车道相关的东西的原因。

标签: c arm neon


【解决方案1】:

有(至少)两种写法。

int64x2_t f(int64x1_t v)
{
    return vdupq_lane_s64(v, 0);
    // or
    // return vcombine_s64(v, v); // poor code with GCC
}

vdupq_lane的输入是64位向量,结果是128位向量。

【讨论】:

  • “GCC 的糟糕代码...” - 完全正确! Clang 在 NEON 内在函数方面做得更好。
  • 如果您有类似这样的简单示例,可以轻松重现并产生较差的代码生成,那么针对 GCC 的错误报告会很有帮助。
猜你喜欢
  • 1970-01-01
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 2013-01-28
  • 1970-01-01
  • 2011-12-29
相关资源
最近更新 更多