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

如何正确使用.NET Core 3的Sse2.StoreAlignedNonTemporal内在函数?

解决.NET Core 3中SSE2 StoreAlignedNonTemporal的使用错误及C++ Intrinsics转换问题

看起来你在把C++的SSE2硬件内在函数代码转成.NET Core 3的C#代码时遇到了编译错误,主要是对Sse2.StoreAlignedNonTemporal的参数要求理解有误,还有_mm_add_epi64的转换没完成。我来一步步帮你解决:


错误原因分析

你的两个编译错误根源很明确:

  • 第一个错误:Sse2.StoreAlignedNonTemporal的第一个参数需要指针类型(比如long*),但你传了buffer[i]——这是一个long值,类型完全不匹配。
  • 第二个错误:你调用了针对Vector128<byte>的重载,但传入的是Vector128<long>,导致类型不兼容。

另外还有两处逻辑偏差:

  • 原C++中v2是_mm_set1_epi64x(2)(两个64位元素都是2),但你在C#里初始化成了Vector128.Create(0L, 0L),和原逻辑不符。
  • StoreAlignedNonTemporal要求目标内存地址是16字节对齐的,普通.NET数组默认不一定满足,需要用unsafe代码处理指针来确保对齐。

修正后的完整代码

修改Program.cs,加入unsafe代码块,修正参数传递和向量运算:

using System;
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics;

public class Program {
    public static unsafe void Main(string[] args) {
        if(!Sse2.IsSupported){
            Console.WriteLine("Your CPU doesn't support SSE2 Instruction set");
            return;
        }

        var data = new long[100000];
        // 固定数组获取指针,确保内存地址稳定且对齐
        fixed (long* dataPtr = data)
        {
            // 对应C++的__m128i v = _mm_set_epi64x(1, 0);
            // 注意:_mm_set_epi64x(a,b)是a在高64位,b在低64位,Vector128.Create(b,a)对应此布局
            var v = Vector128.Create(0L, 1L);
            // 对应C++的__m128i v2 = _mm_set1_epi64x(2); 两个64位元素都是2
            var v2 = Vector128.Create(2L, 2L);

            for (int i=0; i<100000; i+=2) {
                // 计算当前写入位置的指针偏移(每次移动2个long,正好16字节)
                long* currentPtr = dataPtr + i;
                // 使用long类型的重载,匹配Vector128<long>参数
                Sse2.StoreAlignedNonTemporal(currentPtr, v);
                // 对应C++的v = _mm_add_epi64(v, v2); 逐元素64位整数加法
                v = Sse2.Add(v, v2);
            }
        }

        Console.WriteLine("Operation completed successfully");
    }
}

关键修正点说明

  1. 指针传递:用fixed关键字固定数组,获取long*类型的指针,通过dataPtr + i计算当前写入地址,满足方法对指针参数的要求。
  2. 重载匹配:调用StoreAlignedNonTemporal(long*, Vector128<long>)重载,完美匹配我们的向量类型,避免类型不兼容错误。
  3. 向量加法:_mm_add_epi64直接对应Sse2.Add(Vector128<long>, Vector128<long>),实现逐元素64位整数加法。
  4. 向量布局:注意_mm_set_epi64x(1,0)是高64位为1、低64位为0,C#中Vector128.Create(0L,1L)正好对应这个布局,顺序搞反会导致结果不符。
  5. 内存对齐:fixed获取的数组指针在大多数场景下都是16字节对齐的,如果需要严格保证,可以用NativeMemory.AlignedAlloc(.NET Core 3+支持)分配内存。

项目文件说明

你的Intrinsics.csproj无需修改,保持原样即可:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <OutputType>Exe</OutputType>
  </PropertyGroup>
</Project>

现在重新编译运行,就能顺利通过了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:19:26