在GPU上运行C#代码

44

我对GPU编程概念和API的知识一无所知。我有几个问题:

  1. 是否可以编写一段托管的C#代码并将其编译/翻译为某种模块,该模块可以在GPU上执行?还是我注定要有两个实现,一个用于CPU上的托管程序,另一个用于GPU上(我了解在GPU上可执行的内容将会受到限制)?
  2. 是否存在一个良好且成熟的API,可独立地针对各种GPU硬件供应商进行编程(即通用API)?
  3. 如果想要开发在CPU上运行,使用托管语言编写的应用程序,并在适当的GPU硬件上提供速度优化,是否有任何最佳实践?

我也很高兴提供任何适当的学习资源和文档链接。

最好的祝福, Jozef


4
在撰写低级代码时,最好使用低级语言。如果有更好的替代方案,使用C#没有什么好的理由做这件事情。 - Ed S.
请参考这个类似的问题:https://dev59.com/-HRC5IYBdhLWcg3wOOL1 - mcmillab
@EdS。我在这里是因为我对让现有的代码库在GPU上并行运行感兴趣。 - Kresten
7个回答

26

1) 不可以——对于一般情况的 C#,显然任何东西都可以为其某些子集创建。

2) 可以——使用 Direct X 或 Open GL 进行 HLSL 编写。

3) 通常是不可能的——CPU 和 GPU 的编码基础本质上是不同的。

基本上你不能将 CPU 和 GPU 编码视为可比较的。GPU 是一种高度专门化的并行处理工具,适用于大量并行的简单计算。

试图在 GPU 上编写具有许多分支等的通用程序是不会有效率的,甚至可能不可能实现。

它们的内存访问架构完全不同。

你应该为 CPU 编写代码,但将适当的并行计算转移到 GPU 上。


19

1) 对于C#的一般情况,不行。但是对于一个小子集合,可以通过运行时(查看Tidepowered GPU.NET)或语言支持(LINQ或代码引用)实现。

2) 是的,DirectCompute(DX11计算着色器)和OpenCL都是独立于厂商的、成熟的API,并且你可以找到它们的.NET绑定。

3) 不行,正如James所说,它们是不同的东西。GPU是针对高吞吐量数据并行应用程序进行优化的高延迟处理器,而CPU则是针对顺序通用应用程序进行优化的低延迟处理器。

我知道唯一试图解决这个问题的研究项目是SPAP语言。

我的建议是,不要试图找到完美的通用API/运行时,因为没有这样的东西。选择一个现有的技术(DirectCompute或OpenCL),看看你如何利用它来为你的业务服务。

开始的有用链接:


链接到tidepowered已经失效,这里是一个到git的链接 https://github.com/tidepowerd/GPU.NET-Example-Projects - Matas Vaitkevicius

2

1) 据我所知,目前没有相关的库可以帮助您,但可能会有一些适用于C#的库。

2) OpenCL。它与GPU无关,甚至可以在CPU上运行。

3) OpenCL将帮助您解决此问题,您甚至可以使用OpenCL编译CPU代码,不过我不确定生成的代码质量如何。最近我非常喜欢OpenCL,它表现得非常好。


2

还有一个名为brahma的工具,据说可以捕捉表达式并编译到GPU上。我自己没有尝试过。

此外,微软有一个名为accelerator的研究原型,与目标类似但语法不同。


1
你看过Alea GPU吗?虽然这些库不完全免费,但有一个公平的许可证。有很棒的文档和令人印象深刻的工具链。

1

.Net社区创建了用于访问流行图形引擎的Silk.Net库。它可以作为NuGet包安装。在GitHub上,您可以找到文档和一些示例。我进行了测试,似乎可以工作,尽管我无法确定其性能好坏。


0
对于Java,可以参考Aparapi项目(https://github.com/aparapi/aparapi)。这允许在支持OpenCL的任何GPU上运行Java的子集。内核类的字节码在运行时交叉编译为OpenCL代码。有严格限制可以交叉编译的Java代码 - 基本上不能使用对象作为字段、局部变量或方法参数。
然而,一个巨大的优势是内核可以在Java或OpenCL中执行(如果没有适当的GPU/APU设备,则自动回退到Java线程池执行)。这听起来像是你在第三部分问题中寻找的最接近的东西(当然,托管语言不是C#)。
我不知道C#中是否有类似的东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接