使用 F# 和 SIMD 搜索值索引
Posted
技术标签:
【中文标题】使用 F# 和 SIMD 搜索值索引【英文标题】:Using F# and SIMD to search for index of value 【发布时间】:2021-08-22 05:27:14 【问题描述】:我正在研究一种算法,用于搜索数组以查找给定值的索引。我正在尝试遵循.NET Core CLR 中的类似技术。
我感到困惑的是调用BitOperations.TrailingZeroCount
返回的idx
的值。当我搜索2
时,它应该为我正在搜索的数据返回一个索引值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
【问题讨论】:
顺便说一句,如果您使用的是 256 位向量,您可能需要if matches != 0
。 vpmovmskb
会给你一个 32 位的位掩码,所以可以设置符号位。此外,如果您正在线性搜索大于 1 个向量的数组,并且预计第一个匹配不会立即出现,您可能希望将一些比较结果组合在一起,例如 glibc memchr 的做法 (code.woboq.org/userspace/glibc/sysdeps/x86_64/multiarch/…),然后整理出来当您知道 2 或 4 个向量(1 或 2 个缓存行)中存在一个时,匹配的位置。
这正是我所期待的。我一直在研究 SIMD 以快速搜索 int 数组以找到特定值的索引。在我的情况下,数组已排序并且值是唯一的。数组的大小可能在 1K - 10K 元素的范围内。
数组已排序?所以你在二进制搜索让你接近之后使用它?或者您正在使用隐式 quint-tree 或带有 SIMD 的东西来决定接下来要下降 5 个子树中的哪一个...What is the most efficient way to implement a BST in such a way the find(value) function is optimized for random values in the tree on x86? SIMD 对 1k 元素的线性搜索甚至可能不如普通的二进制搜索好。 (如果您希望数据在缓存中很热,请使其无分支。)
问题的完整描述是我有两个数组,A和B。两者都是唯一int的排序数组。对于 A 中的每个元素,我需要在 B 中找到匹配项的索引。由于它们是排序的,我想利用我只需要为 A 中的每个剩余元素搜索 B 中的剩余值。我一直查看 SIMD 以同时执行许多比较。
我明白了。也许蛮力 pcmpgtd
搜索,直到找到更大的,然后 pcmpeqd
看看最后一个向量中是否有匹配项。然后你不会一直走到最后,如果元素存在的话,你就不会走到最后。
【参考方案1】:
Sse2.MoveMask (comparison.AsByte())
(即vpmovmskb
)为每个 int32 匹配结果提供 4 个掩码位,按照您的要求从每个字节中获得一个。
要么使用vmovmskps
(也许是MoveMask(cmp.AsFloat())
,如果F# 是这样做的?)或者处理从bsf
/ tzcnt
获得的字节而不是元素索引。
【讨论】:
以上是关于使用 F# 和 SIMD 搜索值索引的主要内容,如果未能解决你的问题,请参考以下文章