c – 即使在cudaSetDevice之后,第一个cudaMalloc(K40对K20)的速度也很慢

我理解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时间吗?例如This Answer from talonmies

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

提前致谢

解决方法:

1, Why the K40 takes a much longer time (1100ms vs 150ms) for the 1st cudaMalloc? As K40 is supposed to be better than K20

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

2, I thought “cudaSetDevice” can capture the Init time? e.g. This Answer from talonmies

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

3, If the initialization is unavoidable, can process A maintain its status(or context) in GPU while process B is running in the same GPU? I understand I better run GPU in “exclusive” mode, but can process A “suspend” so that it doesn’t need to initialize GPU again later?

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

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

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

上一篇:initGanttView


下一篇:《kernel源码分析(一)配置和编译过程》