返回ARM NEON下的Z标志
returning Z flag under ARM NEON
我有一个NEON函数在做一些比较:
inline bool all_ones(int32x4_t v) noexcept
{
v = ~v;
::std::uint32_t r;
auto high(vget_high_s32(int32x4_t(v)));
auto low(vget_low_s32(int32x4_t(v)));
asm volatile ("VSLI.I32 %0, %1, #16" : "+w"(high), "+w"(low));
asm volatile ("VCMP.F64 %0, #0" : "=w"(high));
asm volatile ("VMRS %0, FPSCR" : "=r"(r) : "w"(high));
return r & (1 << 30);
}
v
的分量(4int)只能是全1或全0。如果所有4个分量都是1,则函数返回true
,否则返回false
。返回部分扩展为3条指令,这对我来说很重要。是否有更好的方法来返回Z标志?
编辑:经过长时间的思考,上面的内容本可以被取代
inline bool all_ones(int32x4_t const v) noexcept
{
return int32_t(-1) == int32x2_t(
vtbl2_s8(
int8x8x2_t{
int8x8_t(vget_low_s32(int32x4_t(v))),
int8x8_t(vget_high_s32(int32x4_t(v)))
},
int8x8_t{0, 4, 8, 12}
)
)[0];
}
NEON中存在掩码提取指令。
如果可以避免的话,你真的不想把NEON和VFP混合在一起。
我建议:
bool all_ones(int32x4_t v) {
int32x2_t l = vget_low_s32(v), h = vget_high_s32(v);
uint32x2_t m = vpmin_u32(vreinterpret_u32_s32(l),
vreinterpret_u32_s32(h));
m = vpmin_u32(m, m);
return vget_lane_u32(m, 0) == 0xffffffff;
}
如果你真的确定唯一的非零值是0xffffffff
,那么你可以放弃比较。独立编译可能会有一些不必要的操作,但当它内联时,编译器应该会解决这个问题。
这似乎奏效了:
inline bool all_ones(int32x4_t v) noexcept
{
v = ~v;
auto high(vget_high_s32(int32x4_t(v)));
auto low(vget_low_s32(int32x4_t(v)));
asm volatile ("VSLI.I32 %0, %1, #16" : "+w"(high), "+w"(low));
return !reinterpret_cast<double&>(high);
}
但是zip和成对添加技巧产生了优越的代码。
相关文章:
- 松弛原子与无同步情况下的记忆连贯性
- vscode下的Arduino代码出现意外编译错误
- 我是c ++的新手,你能解释一下在这种情况下的指针吗
- 在 C/C++ 中打开驻留在 "/sys/" 下的文件时出错
- File.cpp.o:OpenPose 标志 CMakeFiles/.. 的多重定义/main.cpp.o:首先在这里定
- 特定情况下的分段错误
- 矩阵中主对角线下的最高偶数.超大数字的解决方案?
- Cygwin下的gcc 9.3.0预处理器:cmdline -Dname,但名称似乎未定义
- 命令提示符下的 NVCC CUDA 不使用 GPU
- 在 directx11 代码中更改全屏模式下的刷新率不起作用
- 两种情况下的输出不应该相同吗?
- Ubuntu 下的 Cmake 和 Intel IPP 的编译问题
- 如何使它看起来像正在下的雪
- 这种特殊情况下的外部常量
- 为什么 std::swap 不适用于<bool> Clang/Win(英语:Clang/Win)下的矢量元素?
- 为什么'const'在这两种情况下的行为不同?
- 模板模板参数导致Clang下的编译器错误,而不是GCC
- 简单情况下的模板缓冲区行为(GL_ALWAYS、GL_LEQUAL)
- 监视 SDK 下的未定义符号"__Unwind_SjLj_Unregister"
- 返回ARM NEON下的Z标志