1

我知道 CUDA 会在第一次 API 调用期间进行初始化,但是花费的时间太多了。即使在单独的 cudaSetDevice 之后

测试程序:

使用以下代码构建的相同程序:CUDA 7.0 (compute_35) + Visual Studio 2012 + NSight 4.5,然后在 2 台单独的机器上运行(无重建)

在第一个 cudaMalloc 之前,我称之为“cudaSetDevice”</p>

在我的电脑上:Win7 + Tesla K20,第一个 cudaMalloc 需要 150 毫秒

在我的服务器上:Win2012+ Tesla K40,需要1100ms!!

对于两台机器,后续的 cudaMalloc 都快得多。

我的问题是:

1、为什么K40第一个cudaMalloc需要更长的时间(1100ms vs 150ms)?因为K40应该比K20好

2、我以为“cudaSetDevice”可以捕获Init时间?例如来自 talonmies 的这个答案

3、如果初始化是不可避免的,进程A可以在GPU中保持其状态(或上下文)而进程B在同一个GPU中运行吗?我知道我最好在“独占”模式下运行 GPU,但可以处理“暂停”,以便以后不需要再次初始化 GPU?

提前致谢

4

2 回答 2

5

1、为什么K40第一个cudaMalloc需要更长的时间(1100ms vs 150ms)?因为K40应该比K20好

初始化过程的细节没有指定,但是通过观察系统内存量会影响初始化时间。CUDA 初始化通常包括UVM的建立,这涉及到设备和主机内存映射的协调。如果您的服务器的系统内存比您的 PC 多,这是初始化时间差异的一种可能解释。操作系统也可能会产生影响,最后 GPU 的内存大小可能会产生影响。

2、我以为“cudaSetDevice”可以捕获Init时间?例如来自 talonmies 的这个答案

CUDA 初始化过程是一个“惰性”初始化。这意味着将完成足够的初始化过程以支持请求的操作。如果请求的操作是,与请求的操作是cudaSetDevice相比,这可能需要更少的初始化完成(这意味着所需的明显时间可能更短)cudaMalloc。这意味着一些初始化开销可能会被吸收到cudaSetDevice操作中,而一些额外的初始化开销可能会被吸收到后续cudaMalloc操作中。

3、如果初始化是不可避免的,进程A可以在GPU中保持其状态(或上下文)而进程B在同一个GPU中运行吗?我知道我最好在“独占”模式下运行 GPU,但可以处理“暂停”,以便以后不需要再次初始化 GPU?

独立的宿主进程通常会产生独立的CUDA 上下文。CUDA 上下文具有与之关联的初始化要求,因此如果需要初始化新的 CUDA 上下文(可能来自单独的主机进程),则可能已经在设备上初始化了另一个单独的 cuda 上下文这一事实不会提供太多好处。通常,保持进程处于活动状态涉及保持应用程序在该进程中运行。应用程序具有各种“休眠”或暂停行为的机制。只要应用程序没有终止,由该应用程序建立的任何上下文都不需要重新初始化(可能除了如果cudaDeviceReset被调用)。

通常,通过设置 GPU 持久性模式(使用 )允许 GPU 进入深度空闲模式的系统可能会获得一些好处nvidia-smi。但是,这与 GeForce GPU 无关,也与 Windows 系统通常无关。

此外,在多 GPU 系统上,如果应用程序不需要多个 GPU,通常可以通过使用CUDA_VISIBLE_DEVICES 环境变量来避免一些初始化时间,以限制 CUDA 运行时仅使用必要的设备。

于 2015-10-29T01:46:32.547 回答
2

根据编译代码的目标架构和运行代码的架构,JIT 编译可以通过第一个 cudaMalloc(或任何其他)调用启动。“如果未找到二进制代码但 PTX 可用,则驱动程序编译 PTX 代码。” 更多细节:

http://devblogs.nvidia.com/parallelforall/cuda-pro-tip-understand-fat-binaries-jit-caching/

于 2016-01-07T17:14:38.833 回答