使用C#Vector <T> SIMD查找匹配元素的索引 - c#

使用C#的Vector<T>,我们如何最有效地向量化查找集合中特定元素的索引的操作?

作为约束,集合将始终为整数基元的Span<T>,并且最多包含1个匹配元素。

我提出了一个似乎还不错的解决方案,但我很好奇我们能否做得更好。这是方法:

在每个插槽中创建一个仅包含目标元素的Vector<T>
在输入集向量和上一步中的向量之间使用Vector.Equals()可获得一个掩码,该掩码在单个匹配插槽中包含1(如果没有匹配,则仅包含0)。
使用包含从1开始的索引(1、2、3、4,...)的预初始化向量,在该向量和上一步的掩码之间调用Vector.Dot()。每个索引将乘以0,潜在的匹配索引将乘以1。我们得到的是这些乘法的总和,即0或匹配元素的从1开始的索引。
如果结果为0,则返回-1,不匹配。否则,从结果中减去1,使其从0开始,然后返回。

    // One-time initialized vector containing { 1, 2, 3, 4, ... }
    Vector<ushort> indexes = MemoryMarshal.Cast<ushort, Vector<ushort>>(Enumerable.Range(1, Vector<ushort>.Count).Select(index => (ushort)index).ToArray())[0];

    // The input set and the element to search for
    Span<ushort> set = stackalloc ushort[]{ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
    ushort element = 22;

    // Interpret input set as a sequence of vectors (set is assumed to have length power of two for brevity)
    var setVectors = MemoryMarshal.Cast<ushort, Vector<ushort>>(set);

    // Create a vector that contains the target element in each slot
    var elementVector = new Vector<ushort>(element);

    // Loop per vector rather than per element
    foreach (var vector in setVectors)
    {
        // Get a mask that has a 1 in the single matching slot, or only 0s
        var mask = Vector.Equals(vector, elementVector);

        // Get the dot product of the mask and the indexes
        // This will multiple each index by 0, or by 1 if it is the matching one, and return their sum, i.e. the matching index or 0
        // Note that the indexes are deliberately 1-based, to distinguished from 0 (no match)
        var index = Vector.Dot(indexes, mask);

        // Either return 0 for no match, or reduce the index by 1 to get the 0-based index
        return index == 0 ? -1 : index - 1;
    }

参考方案

您希望编译器生成的x86 asm是等值比较(pcmpeqb),pmovmskbmovmskps(矢量到具有1字节或4字节元素的位掩码),然后如果掩码不是-零,对第一个置位(bsftzcnt)进行位扫描。

这将比整数点积更有效!!

您已经有“等于比较”功能,我想我已经看过其他带有Vector-> bitmap内在函数的C#问答。如果有人要编辑此答案或使用自己的C#发布/汇编到此asm的JIT,请这样做。我不知道C#,我只是在这里x86 SIMD。

Java中的<<或>>>是什么意思? - java

This question already has answers here: Closed 7 years ago. Possible Duplicate: What does >> and >>> mean in Java?我在一些Java代码中遇到了一些陌生的符号,尽管代码可以正确编译和运行,但对于括号在此代码中的作用却感…

菱形运算符<>是否等于<?> - java

我在util.TreeSet类中发现,其中一个构造函数正在使用具有空泛型类型的新TreeMap调用另一个构造函数。 public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } new TreeMap<>是什么意思…

将谓词<T>转换为Func <T,bool> - c#

我有一个包含成员Predicate的类,希望在Linq表达式中使用该类:using System.Linq; class MyClass { public bool DoAllHaveSomeProperty() { return m_instrumentList.All(m_filterExpression); } private IEnumerable&…

声纳测试用例失败 - java

我正在尝试为我的项目之一获得声纳报告。我已经运行mvn clean installRunning blah.blah.BlahTest1 Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.016 sec Running blah.blah.BlahTest2 Tests run…

休眠映射<键,设置<值>> - java

我有以下表格:@Entity @Table(name = "events") Event --id --name @Entity @Table(name = "state") State --id --name @Entity @Table(name = "action") Action --id …