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

System.Numerics.Vector.ConditionalSelect用途、用法及示例讲解咨询

详解System.Numerics.Vector.ConditionalSelect

我来把System.Numerics.Vector.ConditionalSelect给你讲透——官方文档确实有点抽象,我用几个实用例子帮你理解它的用途、场景和用法。

核心用途

简单来说,这是.NET SIMD(单指令多数据)编程里的批量条件选择工具:它会同时遍历两个输入向量的每个元素位置,根据第三个条件向量对应位置的布尔值,决定取第一个向量还是第二个向量的元素,最终生成一个新的向量。本质是把循环里的if-else逻辑并行化,用硬件加速提升批量数据处理的性能。

适用场景 & 使用时机

适合的场景

  • 批量数据清洗/修正:比如把数组中所有负数替换为0、把超出范围的像素值截断到合法区间
  • 向量化数值计算:根据不同条件选择不同的计算分支结果(比如大于阈值的数乘2,小于阈值的数除以2)
  • 图像/信号处理:批量处理像素、采样点的条件替换或筛选

什么时候用它?

  • 当你需要对大量数据执行相同的条件选择逻辑时(数据量要远大于Vector<T>.Count,SIMD的并行优势才会明显)
  • 当普通循环里的if-else成为性能瓶颈,想通过硬件并行加速时
  • 已经在使用System.Numerics.Vector进行向量化编程,需要整合条件判断逻辑时

具体用法 & 示例

先说明:Vector<T>.Count的值由当前CPU支持的SIMD宽度决定,比如x64架构下,Vector<float>.Count通常是8,Vector<int>.Count通常是4——代码要适配这个动态值,同时处理剩余的非SIMD批次数据。

示例1:批量替换负数为0

这是最典型的场景,把数组中所有小于0的数替换成0,保留非负数:

using System;
using System.Numerics;

class NegativeToZeroExample
{
    static void Main()
    {
        // 模拟一组包含正负值的测试数据
        float[] input = { -1.2f, 3.4f, -5.6f, 7.8f, -9.0f, 2.3f, -4.5f, 6.7f };
        float[] output = new float[input.Length];

        // 定义替换用的0向量
        Vector<float> zeroVector = Vector<float>.Zero;
        int vectorSize = Vector<float>.Count;

        // 按SIMD批次处理数据
        int i = 0;
        for (; i <= input.Length - vectorSize; i += vectorSize)
        {
            // 从输入数组加载一个向量
            Vector<float> inputVector = new Vector<float>(input, i);
            // 生成条件向量:每个位置标记原元素是否 >= 0
            Vector<float> condition = Vector.GreaterThanOrEqual(inputVector, zeroVector);
            // 执行条件选择:条件为true时取原元素,否则取0
            Vector<float> result = Vector.ConditionalSelect(condition, inputVector, zeroVector);
            // 将结果写回输出数组
            result.CopyTo(output, i);
        }

        // 处理剩余的不足一个向量长度的数据
        for (; i < input.Length; i++)
        {
            output[i] = input[i] >= 0 ? input[i] : 0;
        }

        // 打印结果
        Console.WriteLine("原始数据:");
        Console.WriteLine(string.Join(", ", input));
        Console.WriteLine("\n处理后数据(负数替换为0):");
        Console.WriteLine(string.Join(", ", output));
    }
}

代码解释:

  1. 用Vector.GreaterThanOrEqual生成条件向量:每个位置的元素对应布尔值(true对应全1的位模式,false对应全0)
  2. ConditionalSelect会并行检查每个位置的条件:true取第一个向量的元素,false取第二个向量的元素
  3. 最后把结果向量拷贝回数组,剩余数据用普通循环兜底

示例2:多条件分支的批量处理

如果需要多个条件判断(比如大于10的乘2,小于0的除以2,中间值保持不变),可以多次调用ConditionalSelect叠加逻辑:

using System;
using System.Numerics;

class MultiConditionExample
{
    static void Main()
    {
        float[] input = { 15.2f, -3.4f, 7.6f, 12.8f, -5.0f, 9.3f, -1.5f, 20.7f };
        float[] output = new float[input.Length];

        Vector<float> tenVector = new Vector<float>(10f);
        Vector<float> zeroVector = Vector<float>.Zero;
        Vector<float> twoVector = new Vector<float>(2f);
        int vectorSize = Vector<float>.Count;

        int i = 0;
        for (; i <= input.Length - vectorSize; i += vectorSize)
        {
            Vector<float> inputVec = new Vector<float>(input, i);
            
            // 生成两个条件向量
            Vector<float> greaterThanTen = Vector.GreaterThan(inputVec, tenVector);
            Vector<float> lessThanZero = Vector.LessThan(inputVec, zeroVector);
            
            // 第一步:处理大于10的元素,乘以2
            Vector<float> tempResult = Vector.ConditionalSelect(greaterThanTen, Vector.Multiply(inputVec, twoVector), inputVec);
            // 第二步:处理小于0的元素,除以2
            Vector<float> finalResult = Vector.ConditionalSelect(lessThanZero, Vector.Divide(inputVec, twoVector), tempResult);
            
            finalResult.CopyTo(output, i);
        }

        // 处理剩余元素
        for (; i < input.Length; i++)
        {
            float val = input[i];
            if (val > 10)
                output[i] = val * 2;
            else if (val < 0)
                output[i] = val / 2;
            else
                output[i] = val;
        }

        Console.WriteLine("原始数据:");
        Console.WriteLine(string.Join(", ", input));
        Console.WriteLine("\n处理后数据:");
        Console.WriteLine(string.Join(", ", output));
    }
}

代码解释:

  • 先通过ConditionalSelect处理“大于10”的条件,生成中间结果
  • 再用一次ConditionalSelect处理“小于0”的条件,得到最终结果
  • 这种叠加方式比循环里嵌套if-else效率高得多,因为所有操作都是并行执行的

关键注意事项

  • SIMD兼容性:不同CPU的SIMD宽度不同,Vector<T>.Count会自动适配,所以必须处理剩余的非SIMD批次数据
  • 条件向量的生成:条件向量只能由Vector类的比较方法(GreaterThan、LessThan等)生成,这些方法返回的向量中,true对应全1的位模式,false对应全0
  • 性能收益:只有数据量足够大时(比如上万级别的数组),SIMD的优势才会显现,小数据量用普通循环反而可能更快

内容的提问来源于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:49:31