You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SIMD查找字节数组中未对齐int或long的索引

字节序列中查找整数/长整数的最快实现(x64模式)

核心思路

由于要支持任意字节偏移的扫描,无法依赖对齐的内存访问。最优方案是利用Vector<byte>的SIMD指令批量比较,一次处理多个字节,大幅提升扫描效率——这也是x64平台下的最快实现方式。

代码实现

工具方法:数值转小端序字节数组(适配x86/x64默认内存序)

private static byte[] GetLittleEndianBytes(long value)
{
    var bytes = BitConverter.GetBytes(value);
    if (!BitConverter.IsLittleEndian)
        Array.Reverse(bytes);
    return bytes;
}

private static byte[] GetLittleEndianBytes(int value)
{
    var bytes = BitConverter.GetBytes(value);
    if (!BitConverter.IsLittleEndian)
        Array.Reverse(bytes);
    return bytes;
}

查找首次匹配的索引

public static int FindFirstIndex(byte[] source, long target)
{
    return FindFirstIndex(source, GetLittleEndianBytes(target));
}

public static int FindFirstIndex(byte[] source, int target)
{
    return FindFirstIndex(source, GetLittleEndianBytes(target));
}

private static int FindFirstIndex(byte[] source, byte[] targetBytes)
{
    if (source.Length < targetBytes.Length)
        return -1;

    int targetLen = targetBytes.Length;
    int maxOffset = source.Length - targetLen;
    int vectorSize = Vector<byte>.Count;
    var targetVector = new Vector<byte>(targetBytes);

    // 批量扫描:用SIMD一次处理Vector.Count个字节
    for (int i = 0; i <= maxOffset; i += vectorSize)
    {
        // 处理剩余不足一个Vector的边界部分
        if (i + vectorSize > maxOffset + 1)
        {
            for (int j = i; j <= maxOffset; j++)
            {
                bool match = true;
                for (int k = 0; k < targetLen; k++)
                {
                    if (source[j + k] != targetBytes[k])
                    {
                        match = false;
                        break;
                    }
                }
                if (match)
                    return j;
            }
            return -1;
        }

        // 逐偏移滑动比较当前Vector范围内的所有可能位置
        for (int j = i; j < i + vectorSize && j <= maxOffset; j++)
        {
            var sourceVector = new Vector<byte>(source, j);
            var equals = Vector.Equals(sourceVector, targetVector);
            // 检查所有字节是否完全匹配
            if (Vector.Dot(equals, Vector<byte>.One) == targetLen)
                return j;
        }
    }

    return -1;
}

查找所有匹配的索引

public static List<int> FindAllIndices(byte[] source, long target)
{
    return FindAllIndices(source, GetLittleEndianBytes(target));
}

public static List<int> FindAllIndices(byte[] source, int target)
{
    return FindAllIndices(source, GetLittleEndianBytes(target));
}

private static List<int> FindAllIndices(byte[] source, byte[] targetBytes)
{
    var indices = new List<int>();
    if (source.Length < targetBytes.Length)
        return indices;

    int targetLen = targetBytes.Length;
    int maxOffset = source.Length - targetLen;
    int vectorSize = Vector<byte>.Count;
    var targetVector = new Vector<byte>(targetBytes);

    for (int i = 0; i <= maxOffset; i += vectorSize)
    {
        if (i + vectorSize > maxOffset + 1)
        {
            for (int j = i; j <= maxOffset; j++)
            {
                bool match = true;
                for (int k = 0; k < targetLen; k++)
                {
                    if (source[j + k] != targetBytes[k])
                    {
                        match = false;
                        break;
                    }
                }
                if (match)
                    indices.Add(j);
            }
            return indices;
        }

        for (int j = i; j < i + vectorSize && j <= maxOffset; j++)
        {
            var sourceVector = new Vector<byte>(source, j);
            var equals = Vector.Equals(sourceVector, targetVector);
            if (Vector.Dot(equals, Vector<byte>.One) == targetLen)
                indices.Add(j);
        }
    }

    return indices;
}

性能说明

  • 仅支持x64模式:Vector<byte>在x64下会自动利用128位/256位SIMD寄存器(取决于CPU支持),扫描速度比逐字节循环快3~10倍
  • 小端序适配:自动适配平台内存字节序,确保数值转换后的字节序列正确
  • 边界处理:对末尾不足一个Vector的片段回退到逐字节检查,避免内存越界

内容的提问来源于stack exchange,提问作者Ömer hayyam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 16:24:21