在 C# 中使用 SSE 有可能吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/415375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using SSE in c# is it possible?
提问by Rex Logan
I was reading a question about c# code optimization and one solution was to use c++ with SSE. Is it possible to do SSE directly from a c# program?
我正在阅读一个关于 c# 代码优化的问题,一个解决方案是将 c++ 与 SSE 一起使用。是否可以直接从 ac# 程序进行 SSE?
采纳答案by Amir
The upcoming Mono2.2 release will have SIMD support. Miguel de Icaza blogged about the upcoming feature here, and the API is here.
即将发布的Mono2.2 版本将支持 SIMD。Miguel de Icaza 在这里发表了关于即将推出的功能的博客,API也在这里。
Although there will be a library that will support development under Microsoft's .NET Windows runtime, it will not have the performance benefits that you are looking for unless you run the code under the Mono runtime. Which might be doable depending on your circumstances.
尽管将有一个库支持在 Microsoft 的 .NET Windows 运行时下的开发,但除非您在 Mono 运行时下运行代码,否则它不会具有您正在寻找的性能优势。根据您的情况,这可能是可行的。
Update: Mono 2.2 is released
更新:发布Mono 2.2
回答by Paul Whitehurst
回答by JaredPar
Can C# explicitly make an SSE call?
C# 可以显式地进行 SSE 调用吗?
No. C# cannot produce inline IL much less inline x86/amd64 assembly.
不,C# 不能产生内联 IL,更不能产生内联 x86/amd64 程序集。
The CLR, and more specifically the JIT, will use SSE if it's available removing the need to force it in most circumstances. I say most because I'm not an SSE expert and I'm sure that there are cases where it could be beneficial and the JIT does not make the optimization.
CLR,更具体地说是 JIT,将使用 SSE,如果它可用,在大多数情况下不需要强制它。我说最多是因为我不是 SSE 专家,而且我确信在某些情况下它可能是有益的,而 JIT 不会进行优化。
回答by Filip Fr?cz
Sure you can (the more important question is - why would you? Just leave it to the runtime; that's its job).
你当然可以(更重要的问题是 - 你为什么要这样做?把它留给运行时;这是它的工作)。
C# lets you map a delegate to a memory address. That memory address can contain raw assembly codes. You can read more on Michael Giagnocavo's blog.
C# 允许您将委托映射到内存地址。该内存地址可以包含原始汇编代码。您可以在Michael Giagnocavo 的博客上阅读更多内容。
Although I have not tried myself, it may be possible to use Marshal.GetDelegateForFunctionPointeras well.
虽然我自己没有尝试过,但也可以使用Marshal.GetDelegateForFunctionPointer。
回答by Joe
If you have a 'chunk' of work you want to do, the best bet is to write it in C++ using the MMX/SSE intrinsics and then make a very simple /clr managed C++ class that wraps your functionality and exposes it out as a .net class. Then your code can just use that assembly as if it were a normal class.
如果您有一大堆工作要做,最好的办法是使用 MMX/SSE 内在函数在 C++ 中编写它,然后创建一个非常简单的 /clr 托管 C++ 类来包装您的功能并将其公开为.net 类。然后您的代码可以像使用普通类一样使用该程序集。
For more about the VC intrinsics you can look at this little ditty I wrote many years ago.
有关 VC 内在函数的更多信息,您可以查看我多年前写的这篇小文章。
http://msdn.microsoft.com/en-us/library/0aws1s9k.aspx
http://msdn.microsoft.com/en-us/library/0aws1s9k.aspx
Oh - I'm assuming you are actually wanting to use the parallel functions to speed something up. As others have pointed out - if you just want to move data in larger chunks and the like, the JIT already knows how to use SSE for those basics.
哦 - 我假设您实际上想使用并行函数来加速某些事情。正如其他人指出的那样 - 如果您只想以更大的块等移动数据,JIT 已经知道如何将 SSE 用于这些基础知识。
回答by seljo
Filip is correct. I have another, older post showing a similar, but more detailed example. I have actually run this code, and modified it myself to prove to myself that it works. I am contemplating using this technique in a project I am working and is why I am out looking to see what may be new since this is a bit old. As the author implies, you can write any function you wish in C++, compile it, then copy the bytes into your C#.
菲利普是对的。我有另一个较旧的帖子,展示了一个类似但更详细的例子。我实际上已经运行了这段代码,并自己修改了它以向自己证明它有效。我正在考虑在我正在工作的项目中使用这种技术,这就是为什么我想看看可能是新的,因为这有点旧。正如作者暗示的那样,您可以在 C++ 中编写您想要的任何函数,编译它,然后将字节复制到您的 C# 中。
http://blogs.msdn.com/b/devinj/archive/2005/07/12/438323.aspx
http://blogs.msdn.com/b/devinj/archive/2005/07/12/438323.aspx
I would add that Joe's CLI C++ class is a good idea as well, however, I don't think the sse compiler flag and the /clr flag are compatible on the same project. I just verified that: have to write your high perf code in a separate project to use the SSE (/arch:sse or /arch:sse2) compiler flag as /clr is incomatible. To do anything much more complex than do simple arithmetic on a few inputs, I think this is the best approach.
我想补充一点,Joe 的 CLI C++ 类也是一个好主意,但是,我认为 sse 编译器标志和 /clr 标志在同一个项目中不兼容。我刚刚证实:必须在单独的项目中编写高性能代码才能使用 SSE(/arch:sse 或 /arch:sse2)编译器标志,因为 /clr 是不兼容的。要完成比对几个输入进行简单算术更复杂的事情,我认为这是最好的方法。
回答by KindDragon
SIMD for .NET will be availablein the near future. RyuJIT(the next-generation JIT compiler for .NET) required for this feature ATM.
.NET 的 SIMD 将在不久的将来推出。此功能 ATM 所需的RyuJIT(用于 .NET 的下一代 JIT 编译器)。
You should use Microsoft.Numerics.Vectors.Vector<T>
class from Microsoft.Bcl.Simd packageto take advantage of this feature. Sample code here.
您应该使用Microsoft.Bcl.Simd 包中的Microsoft.Numerics.Vectors.Vector<T>
类来利用此功能。示例代码在这里。
回答by cdiggins
Recently Microsoft has released a beta SIMD vector library (Microsoft.Bcl.Simd) for C# which requires installation of the RyuJIT CTP and works only Windows 8.
最近微软发布了一个用于 C#的测试版 SIMD 矢量库 ( Microsoft.Bcl.Simd),它需要安装 RyuJIT CTP 并且仅适用于 Windows 8。
You can also just used a native SSE library and invoke it from C#. For example the Yeppp library, see this StackOverflow answer.
您也可以只使用本机 SSE 库并从 C# 调用它。例如 Yeppp 库,请参阅此 StackOverflow 答案。
回答by Andreas
回答by DragonSpit
Modern C# Supports SIMD/SSE instructions well and makes them fairly simple to use. Not all instructions are yet supported.
现代 C# 很好地支持 SIMD/SSE 指令并使它们相当易于使用。并非所有指令都受支持。
Here is an example of an SSE .Sum() of an array of uint[]:
这是 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;
}
This particular function is part of an open source and free nuget package, HPCsharp, available on nuget.org, which I maintain.
这个特殊的功能是开源和免费的 nuget 包 HPCsharp 的一部分,可在我维护的 nuget.org 上找到。