我正在阅读有关c#代码优化的问题,一个解决方案是使用带有SSE的c ++。是否可以直接从c#程序进行SSE?
答案 0 :(得分:17)
即将发布的Mono 2.2版本将获得SIMD支持。 Miguel de Icaza在博文中介绍了即将推出的功能here,API为here。
虽然将有一个库可以支持Microsoft的.NET Windows运行时下的开发,但除非您在Mono运行时下运行代码,否则它不会具有您正在寻找的性能优势。根据您的具体情况,这可能是可行的。
更新:单声道2.2为released
答案 1 :(得分:7)
C#可以明确拨打SSE吗?
没有。 C#不能产生内联IL更少的内联x86 / amd64程序集。
CLR,更具体地说是JIT,如果可以使用SSE,则在大多数情况下都不需要强制使用SSE。我说的最多,因为我不是SSE专家,我确信在某些情况下它可能是有益的,JIT不会进行优化。
答案 2 :(得分:5)
SIMD for .NET will be available在不久的将来。此功能ATM需要RyuJIT(.NET的下一代JIT编译器)。
您应该使用Microsoft.Bcl.Simd package中的Microsoft.Numerics.Vectors.Vector<T>
课程来利用此功能。示例代码here。
答案 3 :(得分:4)
基于this论坛发帖,如果SSE在目标计算机上可用,MS JIT编译器会自动使用SSE。
答案 4 :(得分:2)
如果你有一大堆你想做的工作,最好的办法就是用C ++用MMX / SSE内在函数编写它,然后制作一个非常简单的/ clr托管C ++类来包装你的功能并公开它作为.net类。然后你的代码可以像使用普通类一样使用该程序集。
有关VC内在函数的更多信息,你可以看看我多年前写的这个小小的文章。
http://msdn.microsoft.com/en-us/library/0aws1s9k.aspx
哦 - 我假设您实际上想要使用并行功能来加速某些事情。正如其他人所指出的那样 - 如果您只想以更大的块等方式移动数据,JIT已经知道如何将SSE用于那些基础知识。
答案 5 :(得分:2)
菲利普是对的。我有另一个较旧的帖子显示了一个类似但更详细的例子。我实际上已经运行了这段代码,并自己修改它以证明它有效。我正在考虑在我正在工作的项目中使用这种技术,这就是为什么我要看看有什么新的东西,因为这有点旧。正如作者所暗示的,你可以在C ++中编写你想要的任何函数,编译它,然后将字节复制到你的C#中。
http://blogs.msdn.com/b/devinj/archive/2005/07/12/438323.aspx
我想补充说,Joe的CLI C ++类也是一个好主意,但是,我不认为sse编译器标志和/ clr标志在同一个项目上是兼容的。我只是验证了:必须在单独的项目中编写高性能代码以使用SSE(/ arch:sse或/ arch:sse2)编译器标志,因为/ clr是不可用的。要做一些比在几个输入上进行简单算术更复杂的事情,我认为这是最好的方法。
答案 6 :(得分:2)
最近,微软已经为C#发布了一个beta SIMD矢量库(Microsoft.Bcl.Simd),需要安装RyuJIT CTP,只能运行Windows 8。
您也可以使用本机SSE库并从C#调用它。例如,Yeppp库,请参阅this StackOverflow answer。
答案 7 :(得分:2)
答案 8 :(得分:1)
当然可以(更重要的问题是 - 你为什么要这样做?只需将它留给运行时;这就是它的工作)。
C#允许您将委托映射到内存地址。该内存地址可以包含原始汇编代码。您可以在Michael Giagnocavo's blog上阅读更多内容。
虽然我没有尝试过,但也可以使用Marshal.GetDelegateForFunctionPointer。
答案 9 :(得分:1)
现代C#很好地支持SIMD / SSE指令,使它们使用起来相当简单。尚不支持所有说明。
这是uint []数组的SSE .Sum()的示例:
using System.Numerics;
private static ulong SumSseInner(this uint[] arrayToSum, int l, int r)
{
var sumVectorLower = new Vector<ulong>();
var sumVectorUpper = new Vector<ulong>();
var longLower = new Vector<ulong>();
var longUpper = new Vector<ulong>();
int sseIndexEnd = l + ((r - l + 1) / Vector<uint>.Count) * Vector<uint>.Count;
int i;
for (i = l; i < sseIndexEnd; i += Vector<int>.Count)
{
var inVector = new Vector<uint>(arrayToSum, i);
Vector.Widen(inVector, out longLower, out longUpper);
sumVectorLower += longLower;
sumVectorUpper += longUpper;
}
ulong overallSum = 0;
for (; i <= r; i++)
overallSum += arrayToSum[i];
sumVectorLower += sumVectorUpper;
for (i = 0; i < Vector<long>.Count; i++)
overallSum += sumVectorLower[i];
return overallSum;
}
此特定功能是我维护的nuget.org上开放的免费nuget软件包HPCsharp的一部分。