【发布时间】:2018-04-10 17:53:56
【问题描述】:
我想比较两个 16 字节的向量并获取每个匹配的索引。一个小例子来说明我想要什么:
fn get_matching_idx(arr1: &[u8], arr2: &[u8]) {
let vec1 = u8x16::load_aligned(arr1);
let vec2 = u8x16::load_aligned(arr2);
let matches = vec1.eq(vec2);
for i in 0..16 {
if matches.extract_unchecked(i) {
// Do something with the index
}
}
}
理想情况下,我只想为设置的索引“做点什么”,而不是检查每一个(匹配的数量会很少)。
有没有办法使用内在函数获取匹配索引,而不是遍历整个向量?以 gcc 为例,我可以使用 _mm_movemask_epi8 对向量进行位打包,然后重复应用 __builtin_clz 以获取第一个设置位的索引(这对于我将拥有的稀疏数字更有效)。或者,我可以有一个查找表,它为我的位压缩整数中的每个半字节做正确的事情(例如,第一个答案 here)。
rust 中是否有与这些指令等效的指令?
我正在为 Intel x86-64 处理器编译,不需要跨平台支持。
注意:我更喜欢原生(安全)生锈的解决方案,但这不是硬性要求。我可以很好地编写不安全的 rust,甚至可以使用某种 FFI 链接到上述方法。
【问题讨论】:
-
你可以在 Rust 中通过
std::arch使用相同的内在函数:doc.rust-lang.org/nightly/core/arch/x86_64/… --- 请注意,这是一个仅在夜间使用的 API,但计划很快就会稳定下来。如果您需要在稳定的 Rust 上执行此操作,那么最简单的方法可能是在 C 中纠正您的 SIMD 例程。
标签: x86 rust simd intrinsics