这是什么文件?这种最佳实践指南是一个手册,以帮助开发人员获得NVIDIA的最佳性能® CUDA ®图形处理器。它介绍了已建立的并行化和优化技术,并说明了可以大大简化具有CUDA功能的GPU架构编程的编码隐喻和惯用法。
尽管这些内容可以用作参考手册,但您应该了解,在探索各种编程和配置主题时,会在不同的上下文中重新讨论一些主题。因此,建议初学者阅读该指南。这种方法将极大地增进您对有效编程实践的理解,并使您能够更好地使用该指南以供以后参考。
谁应该阅读本指南?本指南中的讨论都使用C ++编程语言,因此您应该很容易阅读C ++代码。
本指南参考并依赖于其他一些可供您参考的文档,可从CUDA网站https://docs.nvidia.com/cn/cuda/免费获得所有这些文档。以下文档是特别重要的资源:
CUDA安装指南
CUDA C ++编程指南
CUDA工具包参考手册
特别是,本指南的“优化”部分假设您已经成功下载并安装了CUDA Toolkit(如果没有,请参考所用平台的相关CUDA安装指南),并且您对CUDA C ++编程语言有基本的了解。和环境(如果没有,请参阅《CUDA C ++编程指南》)。
评估,并行化,优化,部署本指南介绍了针对应用程序的评估,并行化,优化,部署(APOD)设计周期,旨在帮助应用程序开发人员快速识别其代码中最容易从GPU加速中受益的部分,迅速实现这一优势,并开始利用从而尽早加快生产速度。
APOD是一个循环过程:只需很少的初始投资就可以实现,测试和部署初始加速,此时,可以通过确定进一步的优化机会,查看更多的加速,然后部署甚至更快的版本来再次开始该周期。将应用程序投入生产。

评估对于现有项目,第一步是评估应用程序,以找到负责大部分执行时间的代码部分。有了这些知识,开发人员就可以评估这些瓶颈以进行并行化,并开始研究GPU加速。
通过了解最终用户的要求和约束并应用阿姆达尔(Amdahl)和古斯塔夫森(Gustafson)的定律,开发人员可以通过加速应用程序已识别部分来确定性能改进的上限。
并行化在确定了热点并完成了设置目标和期望的基本练习之后,开发人员需要并行处理代码。根据原始代码,这可以像调用现有的GPU优化库一样简单,例如立方玻璃, 傅立叶变换, 要么 推力,也可以像添加一些预处理器指令一样简单,作为对并行化编译器的提示。
另一方面,某些应用程序的设计将需要进行一些重构以暴露其固有的并行性。由于甚至CPU体系结构都需要公开并行性以改善或简单地维护顺序应用程序的性能,因此CUDA并行编程语言家族(CUDA C ++,CUDA Fortran等)旨在使这种并行性的表达尽可能地简单。 ,同时在支持CUDA的GPU上运行,该GPU专为实现最大并行吞吐量而设计。
优化在完成每一轮应用程序并行化之后,开发人员可以着手优化实现以提高性能。由于可以考虑许多可能的优化,因此充分了解应用程序的需求可以帮助使过程尽可能地流畅。但是,与整个APOD一样,程序优化是一个反复的过程(确定优化机会,应用和测试优化,验证所实现的加速并重复),这意味着程序员在看到良好的加速效果之前不必花费大量的时间来记住所有可能的优化策略。相反,可以在学习策略时逐步应用它们。
从重叠的数据传输一直到计算一直到微调浮点操作序列,优化可应用于各种级别。可用的概要分析工具对于指导该过程非常有用,因为它们可以帮助建议开发人员进行优化工作的最佳方案,并为该指南的优化部分的相关部分提供参考。
部署完成应用程序一个或多个组件的GPU加速后,可以将结果与原始预期进行比较。回想一下,初始评估步骤允许开发人员确定通过加速给定热点可获得的潜在提速上限。
在解决其他热点以提高总体速度之前,开发人员应考虑采用部分并行的实现,并将其付诸实践。这很重要,原因有很多;例如,它允许用户尽早从他们的投资中获利(提速可能是部分的,但仍然是有价值的),并且通过为开发者提供渐进而不是[行为6]性的变更,将开发人员和用户的风险降至最低。应用。
建议和最佳做法在本指南中,针对CUDA C ++代码的设计和实现提出了具体的建议。这些建议按优先级进行分类,这是建议的效果及其范围的综合。对于大多数CUDA应用程序而言,具有实质性改进的操作具有最高的优先级,而仅影响非常特殊情况的小型优化则具有较低的优先级。
在实施低优先级建议之前,优良作法是确保已应用所有相关的高优先级建议。这种方法将为所投入的时间提供最佳结果,并避免过早优化的陷阱。
受益标准和确定优先级的范围将根据计划的性质而有所不同。在本指南中,它们代表典型情况。您的代码可能反映了不同的优先级因素。不管这种可能性如何,优良作法都是在进行低优先级项目之前验证没有忽略高优先级建议。
注意:整个指南中的代码示例都省略了错误检查,以确保简洁。但是,生产代码应该系统地检查每个API调用返回的错误代码,并通过调用检查内核启动中的失败cudaGetLastError()。