用C++ AMP和.NET框架进行图像处理

图像处理是一项非常适合GPU计算场景的计算任务。在许多情况下,最常用的算法本质上是大规模并行的,图像中的每个像素都独立于其他像素进行处理。因此,图像处理工具包已经成为新GPGPU编程模型的早期采用者。然而,这些大众市场工具箱中的许多可以更准确地描述为 图像处理 提供“图像输入,图像输出”功能的软件包;换句话说,对于每个操作,存在输入图像和结果输出(操纵)图像。相比之下,一个 图像处理 与此不同的是,工作流的目标通常是描述或提取分析信息,这些信息是在经过多步处理工作流后确定的。这些工作流程通常用于医疗成像等科技行业。

null

在过去的两年里,Core Optical公司一直在为.NET框架构建一个名为 PrecisionImage.NET网站 . 在内部,它围绕两个独立的执行分支,一个针对多核cpu,另一个针对GPU执行。虽然CPU分支是完全管理的CLS兼容的实现,它在很大程度上依赖于.NETFramework的优秀内置线程池,但是GPU分支是使用微软全新的C++ AMP编译器实现的。

在选择我们将用于工具箱的该分支的GPGPU工具时,我们有两个要求。首先,生成的代码需要与供应商无关,这样使用SDK的决定就不会过度限制客户对图形硬件的选择。当前的C++平台的最小平台是DirectX 11,它将很快在英特尔、NVIDIA和AMD之间的GPU中无处不在。其次,由于我们关注的是Microsoft开发人员堆栈,所以我们需要一些能够很好地与.NET框架配合使用的东西。显然C++是AMP最好的选择,因为它是由微软生产的。

对于V1产品,我们发现C++的AMP既坚固又易于编程。尽管微软没有生产一个官方的托管包装器,但是在.NET中访问AMP是一个直接的问题,需要从我们现有的C代码库中进行P/调用。为了将两者之间的表面积保持在最小,我们坚持使用针对CPU回退的托管代码,并将SDK的各种操作压缩为数百个紧凑的AMP内核,这些内核以单精度/双精度和32/64位实现的组合方式编译。在几乎所有情况下,我们发现更简单的untiled模型很容易满足我们的加速目标。如果不是这样的话,我们可以制作一个平铺版本,以最少的戏剧性达到我们的性能目标。

为了展示GPU分支的性能,我们决定 比较速度 两个操作在6内核CPU(多线程托管代码)上运行,而不是运行在Nvidia上的两个不同GPU上的C++ AMP版本。第一个操作被选为GPU实现的理想情况,包括使用AMP的简单的untiled模型实现的大内核的2D卷积。第二种是由于其不适合GPU处理而选择的,并使用平铺模型实现。即使包括将参数从托管代码编组到本机代码的开销,以及将内存复制到GPU或从GPU复制内存的开销,我们在第一个测试用例中也看到了巨大的收益(60倍)。也许更令人惊讶的是在第二个不太合适的测试用例中获得的收益——高达7倍——这表明了AMP编译器的质量。根据我们迄今为止的经验,如果您是一个正在考虑从托管代码库使用AMP的开发人员,我们可以毫无保留地推荐它。

目前,C++ AMP的一个方面对我们的特定用例提出了性能限制(微软承认):CPU和GPU之间的冗余内存复制。这部分是硬件造成的,部分是软件造成的。由于我们的SDK设计为允许轻松组装处理链,因此这些冗余内存副本的开销会迅速增加。微软已经声明这种行为需要改进,我们所有的AMP内核都在使用 阵列视图 当改进到来时利用它的抽象性。这将是一个受欢迎的增强AMP的实施,特别是鉴于AMD最近宣布了他们的hUMA架构倡议。随着硬件和软件都很快到位,我们将看到全新一代的图像处理软件具有前所未有的功能和灵活性。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享