第一个cudaMalloc(K40 vs K20)的缓慢,即使在cudaSetDevice之后

Gen*_*Liu 1 c++ cuda tesla nsight

我理解CUDA会在第一次API调用期间进行初始化,但花费的时间太多了.即使经过单独的cudaSetDevice

测试程序:

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

在第一个cudaMalloc之前,我称之为"cudaSetDevice"

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

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

对于这两台机器,后续的cudaMalloc要快得多.

我的问题是:

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

2,我以为"cudaSetDevice"可以捕获Init时间吗?例如来自talonmies的答案

3,如果初始化是不可避免的,那么当进程B在同一GPU中运行时,进程A是否可以在GPU中保持其状态(或上下文)?我理解我最好在"独占"模式下运行GPU,但可以处理A"暂停",以便以后不需要再次初始化GPU?

提前致谢

Rob*_*lla 5

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

未指定初始化过程的详细信息,但通过观察,系统内存量会影响初始化时间.CUDA初始化通常包括建立UVM,其涉及设备和主机存储器映射的协调.如果您的服务器具有比PC更多的系统内存,则可以解释初始化时间的差异.OS也可能具有效果,最终GPU的存储器大小可能具有效果.

2,我以为"cudaSetDevice"可以捕获Init时间吗?例如来自talonmies的答案

CUDA初始化过程是一个"懒惰"初始化.这意味着将完成足够的初始化过程以支持所请求的操作.如果请求的操作是cudaSetDevice,则可能需要较少的初始化完成(这意味着所需的表观时间可能比所请求的操作更短)cudaMalloc.这意味着一些初始化开销可以被吸收到cudaSetDevice操作中,而一些额外的初始化开销可以被吸收到后续cudaMalloc操作中.

3,如果初始化是不可避免的,那么当进程B在同一GPU中运行时,进程A是否可以在GPU中保持其状态(或上下文)?我理解我最好在"独占"模式下运行GPU,但可以处理A"暂停",以便以后不需要再次初始化GPU?

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

通常,可以通过设置GPU持久性模式(使用nvidia-smi)在允许GPU进入深度空闲模式的系统上获得一些益处.然而,这与GeForce GPU无关,也不一定与Windows系统相关.

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