使用 F# 和 SIMD 搜索值索引

Using F# and SIMD to search for index of value

我正在研究一种算法,用于搜索数组以查找给定值的索引。我正在尝试遵循 .NET Core CLR.

中的类似技术

我感到困惑的地方是 idx 的值,它是 return 通过调用 BitOperations.TrailingZeroCount 编辑的。当我搜索 2 时,它应该 return 我正在搜索的数据的索引值 1 。我得到的是 4。我是否需要将字节偏移量转换回实际类型?这是最有效的写法吗?关于在 .NET 中使用内部函数的文档并不多。

open System
open System.Runtime.Intrinsics.X86
open System.Runtime.Intrinsics
open System.Numerics

#nowarn "9"
#nowarn "20"

[<EntryPoint>]
let main argv =

    let searchSpace : Span<int32> = Span [| 1 .. 8 |]
    let pSearchSpace = && (searchSpace.GetPinnableReference ())
    let search = Sse2.LoadVector128 (pSearchSpace)

    let value = 2
    let values = Vector128.Create value

    let comparison = Sse2.CompareEqual (values, search)
    let matches = Sse2.MoveMask (comparison.AsByte())
    
    if matches > 0 then
        let idx = BitOperations.TrailingZeroCount matches
        printfn "%A" idx // <--- This prints 4 instead of 1

    0 // return an integer exit code

Sse2.MoveMask (comparison.AsByte())(即 vpmovmskb)为每个 int32 匹配结果提供 4 个掩码位,就像您要求的那样来自每个字节。

要么使用 vmovmskps(也许 MoveMask(cmp.AsFloat()),如果 F# 是这样做的?),要么处理字节而不是从 bsf / [=15= 获得的元素索引].