CUDA 常见问题

目录

一般性问题

问: 什么是 CUDA?

CUDA® 既是一个并行计算平台,又是一种编程模型,可利用图形处理器 (GPU) 的能力,显著提高计算性能。

自 2006 年推出以来,CUDA 已被广泛部署于数千种应用程序,在发表的研究论文中亦频频出现,并且受到庞大客户群的支持,已有数以百万计的笔记本电脑、工作站、计算集群和超级计算机安装了支持 CUDA 的 GPU。越来越多的应用程序使用 CUDA 来实现 GPU 加速的优势,应用领域包括天文学、生物学、化学、物理学、数据挖掘、制造业、金融以及其他计算密集型领域。

问: 什么是 NVIDIA Tesla™?

凭借世界上首屈一指的万亿次浮点运算多核处理器,NVIDIA® Tesla™ 计算解决方案实现了向高能效并行计算能力的必要过渡。每个处理器都具有数千个 CUDA 核心,Tesla 可借此进行扩展,快速准确地解决世界上最大的计算难题。

问: 什么是 OpenACC?

OpenACC是编译器指令或提示的一种开放行业标准,编译器指令或提示可插入由 C 语言或 Fortran 语言编写的代码中,从而使编译器生成将在多 CPU 和 GPU 加速系统中并行运行的代码。OpenACC 指令简单而又强大,通过它,可在利用 GPU 计算能力的同时,使代码与其他非加速的仅 CPU 系统兼容。有关详情,请访问 /openacc

问: 与仅 CPU 代码相比,使用 GPU 计算可使性能实现怎样的提升?

这取决于问题在架构上的映射情况。对于数据并行应用程序来说,可实现两个数量级的加速。您可以访问 CUDA 应用页面
,浏览相关研究、开发者、应用程序和合作伙伴。
 

问: CUDA 支持哪些操作系统?

CUDA 支持 Windows、Linux 和 Mac 操作系统。完整列表请参阅最新的 CUDA 工具包发行说明。访问 http://docs.nvidia.com下载最新版本

Q: 哪些 GPU 支持运行 CUDA 加速应用程序?

CUDA 是所有 NVIDIA GeForce、Quadro、Tesla GPU 以及 NVIDIA GRID 解决方案的标准配备。完整列表请参阅 CUDA GPU 页面。

问: 什么是「计算能力」?

GPU 的计算能力决定了它的一般规格和可用功能。有关详情,请参阅《CUDA C 语言编程指南》中的计算能力一节。

问: 在哪里可以找到并行编程的详细介绍?

您可以查看一些大学网络课程、技术在线研讨会、系列文章以及并行计算方面的优秀书籍。这些内容可在我们的 CUDA 教育页面找到。

硬件和架构

问:下一版新 GPU 架构发布后,我必须要重写 CUDA 内核吗?

不是。CUDA C/C++ 提供了一种抽象方法,您可以借此说明自己希望以何种方式执行程序。编译器所生成的 PTX 代码也不是专门针对硬件的。在运行时,PTX 代码会针对特定目标 GPU 进行编译 - 这是驱动程序的任务,驱动程序会随新版 GPU 的发布而进行更新。寄存器数量和共享内存大小的更改可能会为进一步优化提供机会,但这是可选的。因此,您现在编写的代码可在未来的 GPU 中执行

问: CUDA 支持在一个系统中使用多个显卡吗?

支持。应用程序可将工作分配到多个 GPU。但是这并不是自动完成的,因此应用程序拥有全面控制权。请参阅 GPU 计算 SDK 中的「multiGPU」示例,查看使用多 GPU 进行编程的示例。

问: 在哪里可以找到有关 NVIDIA GPU 架构的更多信息?

以下是两个非常有用的资源:

编程问题

我在 CUDA 中发现了一个问题,该如何报告此问题?
请以 CUDA 注册开发人员的身份进行注册,在应用程序获得批准后,您可以提交问题以供 NVIDIA 工程团队审核。

问题报告应包含一段用于说明问题的简单、独立的代码,以及对于问题和预期行为的描述。
请在问题报告中加入以下信息:

  • 机器配置 (CPU、主板、内存等)
  • 操作系统
  • CUDA 工具包版本
  • 显示驱动程序版本
  • 如果您是 Linux 用户,请附上运行「nvidia-bug-report.sh」所生成的 nvidia-bug-report.log 文件。

 

问: CUDA 如何建构计算?

CUDA 基本上遵循数据并行计算模型。通常,每个线程会对并行数据的不同元素执行相同的操作。

数据被划分为 1D、2D 或 3D 网格块。每个区块在外型上可以是 1D、2D 或 3D,并且在当前硬件中由 512 多个线程组成。线程块中的线程可通过共享内存联合发挥作用。
线程块作为较小的线程组 (即「线程束」) 来执行。

问:CPU 和 GPU 可以并行运行吗?

CUDA 中的内核调用是异步的,因此在启动内核之后,驱动程序会将控制权交还给应用程序。



衡量性能时应使用「cudaThreadSynchronize()」API 调用,以确保在停止计时器之前完成所有设备操作。



负责执行内存拷贝和控制图形互操作性的 CUDA 函数是同步的,会隐式等待所有内核完成运行。


问: 我可以针对流式传输应用程序并行传输数据和运行内核吗?
可以,CUDA 支持使用 CUDA 流同时进行 GPU 计算和数据传输。有关详情,请参阅《CUDA C 语言编程指南》的异步并发执行一节。

问: 可以从其他 PCI-E 设备直接 DMA 到 GPU 内存吗?

您可以通过 GPUDirect 直接 DMA 到 GPU 主机内存。有关详情,请参阅 GPUDirect 技术页面。

问: CPU 与 GPU 之间的传输速率峰值是多少?
内存传输性能受许多因素的影响,包括传输的大小以及所用系统主板的种类。

在 PCI-Express 2.0 系统中,我们测量到传输速率高达 6.0 GB/秒。
您可以使用 SDK 中的带宽测试样例来测量系统带宽。

通过锁页内存传输的速度较快,因为 GPU 可以直接从此内存进行 DMA。但是分配过多锁页内存会大大影响系统的整体性能,因此需谨慎分配。

问: CUDA 中数学运算的精度如何?
所有目前的 NVIDIA GPU 和自 GT200 以来的 GPU 均支持双精度浮点运算。有关详情,请参阅编程指南。所有具有运算能力的 NVIDIA GPU 均支持 32 位整数和单精度浮点运算。他们遵循单精度二进制浮点运算的 IEEE-754 标准,仅存在一些细微差别。


问: 为什么我的 GPU 计算结果与 CPU 结果略有不同
之所以不同可能会有很多原因。浮点运算无法保证在任何处理器架构中都给出完全相同的结果。在 GPU 上按数据并行方式实施算法时,运算顺序通常是不同的。

以下文章是关于浮点运算的非常有用的参考资料:
 Precision & Performance:Floating Point and IEEE 754 Compliance for NVIDIA GPUs (精度和性能: NVIDIA GPU 的浮点和 IEEE 754 合规要求)

问: CUDA 是否支持双精度运算?
支持。计算能力在 1.3 和 1.3 以上的 GPU 支持在硬件中进行双精度浮点运算。

问: 如何在内核中使用双精度浮点运算?
您需要向 nvcc 命令行添加开关语句「-arch sm_13」(或更高的计算能力),否则双精度将静默降级为浮点数。请参阅 CUDA 安装程序中的「Mandelbrot」示例,了解如何根据 GPU 的计算能力在不同的内核之间进行切换。

问:是否可以从纹理中读取双精度浮点数?
硬件不支持将双精度浮点作为纹理格式,但是,如果您不需要插值,便可以使用 int2 并将其转换为双精度:

texture<int2,1> my_texture;

static __inline__ __device__ double fetch_double(texture<int2, 1> t, int i)
{
int2 v = tex1Dfetch(t,i);
return __hiloint2double(v.y, v.x);
}

问: CUDA 是否支持长整数?
支持。CUDA 支持 64 位整数 (超长整数)。对这些整数类型的运算可根据计算能力在一些 GPU 上编译为多指令序列。

问:在哪里可以找到有关 PTX 汇编语言的文档?
您可从 CUDA 工具包文档中找到此类文档。

问: 如何查看我的程序生成的 PTX 代码?
在 nvcc 命令行中添加「-keep」(或在 Visual Studio 中自定义设备设置) 可保留中间编译文件。然后查看「.ptx」文件即可。

问: 如何查看内核所用的寄存器数量或共享/常量内存大小?
在 nvcc 命令行中添加「--ptxas-options=-v」选项即可。在编译过程中,此信息将输出至控制台。

问: 是否可以同时执行多个内核?
可以。计算能力在 2.x 或 2.x 以上的 GPU 支持并发内核执行和启动。

问: CUDA 内核的最大长度是多少?
这由 GPU 的计算能力所决定,如需了解确切答案,请参阅《CUDA C 语言编程指南》的「功能和技术规格」一节。

问: 如何调试 CUDA 代码?
您可以使用多款强大的调试工具来创建断点和跟踪。主要操作系统以及多 GPU 解决方案和集群均有相应的工具可用。请访问 CUDA 工具和生态系统页面,了解最新的调试工具

问: 如何优化 CUDA 代码?

现在我们提供了大量有关如何优化 CUDA 代码的指南和示例供您参考。以下是一些有用的链接:

问: 如何选择每个区块的最优线程数?
为了充分利用 GPU,您应谨慎平衡每个线程块的线程数、每个区块的共享内存大小以及内核所用的寄存器数量。

您可以使用 CUDA 占用率计算器工具来按给定 CUDA 内核计算 GPU 的多处理器占用率。该工具包含在最新的 CUDA 工具包中。
 

问: 内核执行所需的最长时间是多久?
在 Windows 系统上,启动单个 GPU 程序的最长运行时间约为 5 秒。超过这一时间限制通常会导致启动失败 (通过 CUDA 驱动程序或 CUDA 运行时间报告),但有时会导致整个机器中止运行,需要硬重置才能解决问题。

此问题是由 Windows「监视器」计时器所致,如果使用主要图形适配器的程序的运行时间超过了允许的最长时间,该计时器便会导致程序超时。

鉴于这个原因,建议您在没有连接显示器并且没有扩展 Windows 桌面的 GPU 上运行 CUDA。在这种情况下,系统必须至少包含一个用作主要图形适配器的 NVIDIA GPU。

问:如何计算 GPU 上的数组之和?
该计算方法称为并行规约运算。有关详情,请参阅「规约」示例

问: 如何从每个线程中输出不定量的数据?
使用并行前缀和 (也称作「scan」) 运算可以实现。CUDA 数据并行基元库 (CUDPP) 包括高度优化的 scan 函数:

http://www.gpgpu.org/developer/cudpp/

The "marchingCubes" 示例展示了 scan 针对每个线程的不同输出的用法。

问: 如何在 GPU 上排列数组?
我们提供的「particles」示例包括快速并行基数排序。
要排列一个区块中的数值组,您可以使用并行双调排序。 另请参阅「bitonic」示例。
Thrust 库也包括排序函数。有关更多示例信息,请参阅在线示例文档

问:分配 CUDA 应用程序需要什么?
使用驱动程序 API 的应用程序只需要 CUDA 驱动程序库 (在 Windows 下为「nvcuda.dll」),在进行标准 NVIDIA 驱动程序安装时会安装该库。

使用运行时间 API 的应用程序还需要运行时间库 (在 Windows 下为「cudart.dll」),该库可在 CUDA 工具包中找到。您可以根据 CUDA 工具包中随附的最终用户许可证协议,在应用程序中分配此库。

问:如何从应用程序中获得有关 GPU 温度的信息?
在 Microsoft Windows 平台上,您可以通过 NVIDIA 的 NVAPI 查看 GPU 温度和许多其他低级 GPU 功能

在 Linux 下,标准驱动程序安装中的「nvidia-smi」实用程序也可显示所有已安装设备的 GPU 温度。

工具、库和解决方案

问: 什么是 CUFFT?
CUFFT 是一种适用于 CUDA 的快速傅里叶变换 (FFT) 库。有关详情,请参阅 CUFFT 文档。

问: CUFFT 支持哪些转换类型?
当前版本支持 Complex to Complex (C2C)、Real to Complex (R2C) 和 Complex to Real (C2R)。

问: 最大转换大小是多少?
对于 1D 转换而言,在 1.0 版本中的最大转换大小是 16M 元素。

问: 什么是 CUBLAS?
CUBLAS 是 CUDA 驱动程序顶部基本线性代数子程序 (BLAS) 的实施。您可以通过其访问 NVIDIA GPU 计算资源。该库在 API 层独立存在,也就是说,不必与 CUDA 驱动程序进行直接互动。

问: NVIDIA 在 Linux 和 MAC 上有 CUDA 调试器吗?
有,CUDA-GDB 是适用于 Linux 发行版和 MAC OSX 平台的 CUDA 调试器。

问:CUDA-GDB 是否支持 UI?
CUDA-GDB 是一种命令行调试器,但是可与 Data Display Debugger、Emacs 和 XEmacs 等 GUI 前端配合使用。此外还有第三方解决方案,如需查看选项列表,请参阅我们的工具和生态系统页面

问: Parellel Nsight 与 CUDA-GDB 的主要区别是什么?
两者之间有很多共同特征,以下是其区别:
Parallel Nsight
在 Windows 系统中运行,可以在 GPU 上调试图形和
CUDA 代码 (无法调试 CPU 代码)。

CUDA-GDB 在 Linux 和 Mac OS 系统中运行,可以在 GPU 上调试 CPU 代码和 CUDA 代码 (无法在 GPU 上调试图形)。

问: 如何使用交互式桌面调试 OGL+CUDA 应用程序?
您可以 ssh 或使用 nxclient 或 vnc 来远程调试 OGL+CUDA 应用程序。这要求用户在 X 服务器配置文件中禁用交互式会话。有关详情,请参阅《CUDA-GDB 用户指南》。

问: 集群调试应使用哪种调试器?
NVIDIA 与合作伙伴联合提供了集群调试器。支持 CUDA 的集群调试器有两种: Allinea 提供的 DDT 和 RogeWave Software 提供的 TotalView 调试器

问: -G 标志对于代码优化有什么影响?
-G 标志关闭了 CUDA 代码上的大多数编译器优化。由于某些优化需用于保证应用程序正常运行,因此无法关闭。例如:局部变量不会溢出到本地内存,而是会保存到寄存器中,调试器会跟踪寄存器的活动范围。要使应用程序在没有调试标记的情况下正常启动,需要确保在调试模式下进行编译时,该应用程序不会耗尽内存。

问: 如有其他问题,该如何与调试器团队联系?
请发送电子邮件至 cuda-debugger-bugs@nvidia.com

与 NVIDIA 互动

问: 如何发送有关改进 CUDA 工具包的建议?

成为注册开发人员,然后您便可以直接使用问题报告系统提出建议和请求,还可以报告问题等。

问: 我可以直接向 CUDA 团队提问问题吗?
您可以在一年一度的 GTC 会议上与我们的团队直接面对面交流,请访问 www.gputechconf.com 了解下一届 GTC 的召开日期

您还可以参加直播的问答在线研讨会,直接向某些一流的 CUDA 工程师提问。立即参加,成为注册开发人员