如何正确使用.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"); } }
关键修正点说明
- 指针传递:用
fixed关键字固定数组,获取long*类型的指针,通过dataPtr + i计算当前写入地址,满足方法对指针参数的要求。 - 重载匹配:调用
StoreAlignedNonTemporal(long*, Vector128<long>)重载,完美匹配我们的向量类型,避免类型不兼容错误。 - 向量加法:
_mm_add_epi64直接对应Sse2.Add(Vector128<long>, Vector128<long>),实现逐元素64位整数加法。 - 向量布局:注意
_mm_set_epi64x(1,0)是高64位为1、低64位为0,C#中Vector128.Create(0L,1L)正好对应这个布局,顺序搞反会导致结果不符。 - 内存对齐:
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
相关产品推荐
相关产品推荐

