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

如何用SIMD统计数组中指定字节的出现次数?附代码示例疑问

使用SIMD统计数组中指定字节的出现次数

首先,你已经走对了第一步——用异或来定位匹配字节:当原字节和目标字节(55)相等时,异或结果会是0,这个逻辑完全没问题。接下来的核心是把这些0的位置转换成可计数的标识,再高效累加统计数量,下面一步步给你拆解:

1. 从异或结果生成匹配掩码

异或后值为0的位置就是我们要找的匹配项,我们可以用SIMD的Vector.Equals方法,把异或结果和全0向量做比较,生成一个掩码向量:

var xorResult = Vector.Xor(vBytes, mask);
// 匹配的位置会被设为byte类型的最大值0xFF,不匹配则为0
var matchMask = Vector.Equals(xorResult, Vector<byte>.Zero);

其实更直接的方式是跳过异或,直接用Vector.Equals(vBytes, mask)生成同样的掩码,这样少一步运算,效率会更高~

2. 统计掩码中匹配项的数量

现在matchMask里,每个匹配的位置都是0xFF(即255),不匹配的是0。我们需要统计有多少个0xFF,这里有两种高效的实现方式:

方法1:SIMD扩展与累加

把byte向量扩展为更大的整数类型(比如ushort),然后用Vector.Sum累加所有值,最后除以255得到次数:

// 将byte向量扩展为ushort向量(每个0xFF变为0x00FF)
var widened = Vector.Widen(matchMask, matchMask);
// 累加所有ushort值
var total = Vector.Sum(widened);
// 每个匹配项贡献255,所以总和除以255就是次数
int count = (int)(total / 255);

方法2:分组整数累加(适合大数组场景)

如果处理的是超大数组,你可以把byte掩码直接转换为int向量(每4个byte合并为一个int),再累加:

// 将byte掩码转换为int向量(每4个byte打包成一个int)
var intMask = Vector.AsVectorInt32(matchMask);
// 累加所有int值
var intSum = Vector.Sum(intMask);
// 每个匹配的byte贡献255,总和除以255得到次数
int count = intSum / 255;

针对你的示例验证

你的输入向量vBytes中,值为55的字节出现在索引2、6、11、13、14,共5次。用上面的代码计算,最终count会是5,和手动统计的结果完全一致。

完整的数组处理示例(针对大数组)

如果要处理整个数组而非单个向量,你可以参考这个完整实现:

int CountByteSimd(byte[] array, byte target)
{
    int count = 0;
    var targetVec = new Vector<byte>(target);
    int vectorSize = Vector<byte>.Count;
    int i = 0;

    // 处理完整的SIMD块
    for (; i <= array.Length - vectorSize; i += vectorSize)
    {
        var vec = new Vector<byte>(array, i);
        var matchMask = Vector.Equals(vec, targetVec);
        var intMask = Vector.AsVectorInt32(matchMask);
        count += Vector.Sum(intMask) / 255;
    }

    // 处理剩余的元素(不足一个SIMD向量的部分)
    for (; i < array.Length; i++)
    {
        if (array[i] == target)
            count++;
    }

    return count;
}

内容的提问来源于stack exchange,提问作者MaYaN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:53:52