首页 / 专利库 / 软件 / 操作系统 / 进程 / 子进程 / 一种通过API截获对GPU进行资源管理的方法

一种通过API截获对GPU进行资源管理的方法

阅读:561发布:2020-05-08

专利汇可以提供一种通过API截获对GPU进行资源管理的方法专利检索,专利查询,专利分析的服务。并且本 发明 公开了一种通过API截获对GPU进行资源管理的方法,包括:显存分配管理,拦截CUDA运行时的所有cudaMalloc函数,在用户调用cudaMalloc函数时,控制流跳转,按照预设好的显存分配规则和显存分配限额来进行显存分配的管理;流处理器分配,在执行到CUDA核函数的调用时,控制流跳转,按照预设好的流处理器分配规则来进行流处理器分配的管理。本发明通过API截获实现控制流跳转,进而可根据预设好的分配规则等对GPU进行资源管理,克服了一人独占所有GPU资源的问题,且无需对源程序代码进行过多 修改 ,具有实现方便、成本低的优点。,下面是一种通过API截获对GPU进行资源管理的方法专利的具体信息内容。

1.一种通过API截获对GPU进行资源管理的方法,其特征在于,显存分配管理,拦截CUDA运行时的所有cudaMalloc函数,在用户调用cudaMalloc函数时,控制流跳转,按照预设好的显存分配规则和显存分配限额来进行显存分配的管理;
流处理器分配,在执行到CUDA核函数的调用时,控制流跳转,按照预设好的流处理器分配规则来进行流处理器分配的管理。
2.根据权利要求1所述的通过API截获对GPU进行资源管理的方法,其特征在于,控制流跳转,按照预设好的显存分配规则和显存分配限额来进行显存分配的管理的方法是:先判断当前显存分配请求是否符合预设好的显存分配规则,且显存分配限额是否剩余,如果都符合则将此次显存分配请求转发到对应的cudaMalloc函数中,然后CUDA库里的函数就会跟在没有拦截的情况下一样正常分配显存,否则将显存分配失败的信息返回给CUDA客户代码。
3.根据权利要求2所述的通过API截获对GPU进行资源管理的方法,其特征在于,显存分配管理的步骤是:
(1-1)在CUDA应用程序中,CUDA用户代码通过调用一族cudaMalloc*函数,来指示CUDA运行时库进行显存分配;这里一族cudaMalloc*函数表示一系列函数,包括函数cudaMalloc、cudaMallocHost、cudaMallocPitch、cudaMalloc3D,cudaMalloc表示特指函数cudaMalloc;
(1-2)此时,所有的cudaMalloc*函数都已被拦截,在用户调用cudaMalloc*函数的时候,控制流跳转到对应的cudaHookMalloc*函数中;
(1-3)控制流进入到cudaHookMalloc*函数后,cudaHookMalloc*函数根据预设好的显存分配规则和显存分配限额,对客户代码的此次显存分配请求进行是否符合显存分配规则的判断,然后查询显存分配限额还有没有剩余;
(1-4)若此次显存分配请求符合显存分配规则,且显存分配限额仍有剩余,则cudaHookMalloc*函数,会将来自CUDA客户代码的显存分配请求,转发到对应的CUDA运行时的cudaMalloc*函数中,并将cudaHookMalloc*函数返回的成功信息或者失败信息返回给CUDA客户代码;
(1-5)若此次显存分配请求不符合显存分配规则,或显存分配限额没有剩余,则cudaHookMalloc*函数会直接将显存分配失败的信息返回给CUDA客户代码,由CUDA客户代码对显存分配失败的异常进行处理,或者直接结束CUDA程序。
4.根据权利要求1所述的通过API截获对GPU进行资源管理的方法,其特征在于,流处理器分配,包括方法:
(2-1)在CUDA应用程序中,CUDA用户代码通过编写CUDA核函数,并通过三对尖括号的语法,指定CUDA核运行的网格和线程大小;
(2-2)NVCC工具在编译CUDA  C++代码时,将三对尖括号的语法,转化为对cudaLaunchKernel函数的调用,运行的网格和线程块大小,转化为cudaLaunchKernel函数的gridDim和blockDim参数;
(2-3)在执行到CUDA核函数的调用时,编译好的代码会调用cudaLaunchKernel函数,此时,控制流跳转到cudaHookLaunchKernel函数中;
(2-4)在cudaHookLaunchKernel函数中,程序根据预先设置好的流处理器分配规则,判断此次分配请求是否符合流处理器分配规则,若不符合,则向用户代码返回启动核函数失败的错误,让CUDA用户代码自行处理错误或终止程序。
5.根据权利要求1所述的通过API截获对GPU进行资源管理的方法,其特征在于,API截获是指可执行文件通过动态加载的方法调用动态共享库里的API函数,通过对这些调用进行拦截并重定向到另外编写的函数的方法,在windows下实现时,动态共享库属于PE文件格式,具体的扩展名为.dll,采用由Microsoft开发的开源API拦截程序库Detours作为API拦截技术。
6.根据权利要求5所述的通过API截获对GPU进行资源管理的方法,其特征在于,使用Detours前,源程序对CUDA库的调用采用动态链接,即加载dll的方式进行。
7.根据权利要求6所述的通过API截获对GPU进行资源管理的方法,其特征在于,设置一个独立的程序启动器用于代理启动CUDA客户程序,在启动启动器的时候,通过命令行参数传递CUDA客户程序的路径。
8.根据权利要求7所述的通过API截获对GPU进行资源管理的方法,其特征在于,程序启动器启动后,通过调用Detour库的函数DetourCreateProcessWithDllEx,将CUDA拦截dll注入到CUDA客户程序内,并启动CUDA客户程序进程
9.根据权利要求6所述的通过API截获对GPU进行资源管理的方法,其特征在于,启动CUDA客户程序进程后,windows的dll加载机制随后会调用拦截dll内的dllmain函数,在dllmain函数中,会调用DetourAttach函数,此函数将一个无条件跳转指令插入到目标函数最前面,达到API拦截的目的。
10.根据权利要求5所述的通过API截获对GPU进行资源管理的方法,其特征在于Windows钩子函数的行为与对应的CUDA函数一致;
在编译拦截dll的时候,显式地用关键字__declspec(dllimport)向MSVC告知此拦截函数是通过dll共享导入的。

说明书全文

一种通过API截获对GPU进行资源管理的方法

技术领域

[0001] 本发明涉及计算机内部GPU资源管理研究领域,特别涉及一种通过API截获对GPU进行资源管理的方法。

背景技术

[0002] 随着深度学习相关应用越来越广泛,不可避免的要用到GPU。大量非商业机构和科研机构出于成本的原因,都会使用NVIDIA消费级GPU(GTX、RTX等系列)来进行深度学习相关应用的网络训练。
[0003] NVIDIA消费级GPU通常是用作个人电脑的显卡,且出于商业利益原因,NVIDIA并没有给消费级GPU配备资源管理的相关功能,因此在多人共同使用的安装了NVIDIA消费级GPU的服务器上,资源管理一直是一个重大问题,常常会出现一人独占了所有GPU资源,导致其他人无GPU资源可用的困境。这里的GPU资源主要指GPU上的显存和流处理器两大类资源。NVIDIA为专业级的显卡提供了虚拟化GPU的功能(Tesla、Pascal等系列),但并没有对消费级显卡进行支持,因此不能满足低成本的要求。
[0004] 为此,研究一种针对NVIDIA消费级GPU的、可用的、成熟的资源管理方法具有重要的应用价值。

发明内容

[0005] 本发明的目的在于克服现有技术的缺点与不足,提供一种通过API截获对GPU进行资源管理的方法,该方法基于API拦截技术,尤其是对NVIDIA消费级GPU可进行资源管理。
[0006] 本发明的目的通过以下的技术方案实现:一种通过API截获对GPU进行资源管理的方法,包括:
[0007] 显存分配管理,拦截CUDA运行时的所有cudaMalloc函数,在用户调用cudaMalloc函数时,控制流跳转,按照预设好的显存分配规则和显存分配限额来进行显存分配的管理;
[0008] 流处理器分配,在执行到CUDA核函数的调用时,控制流跳转,按照预设好的流处理器分配规则来进行流处理器分配的管理。
[0009] 本发明均通过API截获实现控制流跳转,进而可根据预设好的分配规则等对GPU进行资源管理,克服了一人独占所有GPU资源的问题,且无需对源程序代码进行过多修改,具有实现方便、成本低的优点。
[0010] 优选的,控制流跳转,按照预设好的显存分配规则和显存分配限额来进行显存分配的管理的方法是:先判断当前显存分配请求是否符合预设好的显存分配规则,且显存分配限额是否剩余,如果都符合则将此次显存分配请求转发到对应的cudaMalloc函数中,然后CUDA库里的函数就会跟在没有拦截的情况下一样正常分配显存,否则将显存分配失败的信息返回给CUDA客户代码。
[0011] 更进一步的,显存分配管理的步骤是:
[0012] (1-1)在CUDA应用程序中,CUDA用户代码通过调用一族cudaMalloc*函数,来指示CUDA运行时库进行显存分配;这里一族cudaMalloc*函数表示一系列函数,包括cudaMalloc、cudaMallocHost、cudaMallocPitch、cudaMalloc3D,cudaMalloc表示特指函数cudaMalloc;
[0013] (1-2)此时,所有的cudaMalloc*函数都已被拦截,在用户调用cudaMalloc*函数的时候,控制流跳转到对应的cudaHookMalloc*函数中;
[0014] (1-3)控制流进入到cudaHookMalloc*函数后,cudaHookMalloc*函数根据预设好的显存分配规则和显存分配限额,对客户代码的此次显存分配请求进行是否符合显存分配规则的判断,然后查询显存分配限额还有没有剩余;
[0015] (1-4)若此次显存分配请求符合显存分配规则,且显存分配限额仍有剩余,则cudaHookMalloc*函数,会将来自CUDA客户代码的显存分配请求,转发到对应的CUDA运行时的cudaMalloc*函数中,并将cudaHookMalloc*函数返回的成功信息或者失败信息返回给CUDA客户代码;
[0016] (1-5)若此次显存分配请求不符合显存分配规则,或显存分配限额没有剩余,则cudaHookMalloc*函数会直接将显存分配失败的信息返回给CUDA客户代码,由CUDA客户代码对显存分配失败的异常进行处理,或者直接结束CUDA程序。
[0017] 优选的,流处理器分配,包括方法:
[0018] (2-1)在CUDA应用程序中,CUDA用户代码通过编写CUDA核函数,并通过三对尖括号的语法,指定CUDA核运行的网格和线程大小;
[0019] (2-2)NVCC工具在编译CUDA C++代码时,将三对尖括号的语法,转化为对cudaLaunchKernel函数的调用,运行的网格和线程块大小,转化为cudaLaunchKernel函数的gridDim和blockDim参数;
[0020] (2-3)在执行到CUDA核函数的调用时,编译好的代码会调用cudaLaunchKernel函数,此时,控制流跳转到cudaHookLaunchKernel函数中;
[0021] (2-4)在cudaHookLaunchKernel函数中,程序根据预先设置好的流处理器分配规则,判断此次分配请求是否符合流处理器分配规则,若不符合,则向用户代码返回启动核函数失败的错误,让CUDA用户代码自行处理错误或终止程序。
[0022] 优选的,API截获是指可执行文件通过动态加载的方法,调用动态共享库里的API函数,通过对这些调用进行拦截并重定向到另外编写的函数的方法,在windows下实现时,动态共享库属于PE文件格式,具体的扩展名为.dll,采用由Microsoft开发的开源API拦截程序库Detours作为API拦截技术。
[0023] 更进一步的,使用Detours前,源程序对CUDA库的调用采用动态链接,即加载dll的方式进行。
[0024] 优选的,设置一个独立的程序启动器用于代理启动CUDA客户程序,在启动启动器的时候,通过命令行参数传递CUDA客户程序的路径。这里命令行参数是指启动进程时带的参数。
[0025] 更进一 步的 ,程 序启动器 启动后,通过 调用Deto ur库的函 数DetourCreateProcessWithDllEx,将CUDA拦截dll注入到CUDA客户程序内,并启动CUDA客户程序进程。
[0026] 更进一步的,启动CUDA客户程序进程后,windows的dll加载机制随后会调用拦截dll内的dllmain函数,在dllmain函数中,会调用DetourAttach函数,此函数将一个无条件跳转指令插入到目标函数最前面,达到API拦截的目的。
[0027] 优选的,Windows钩子函数的行为与对应的CUDA函数一致。避免在引入其他调用了CUDA的第三方库的代码的时候出现错误。
[0028] 优选的,在编译拦截dll的时候,显式地用关键字__declspec(dllimport)向MSVC告知此拦截函数是通过dll共享导入的。以避免MSVC对此函数生成模块内部的调用版本,只能在此模块内跳转到目标函数。
[0029] 本发明与现有技术相比,具有如下优点和有益效果:
[0030] 本发明基于API拦截技术,对源程序的CUDA调用进行拦截,可达到对源程序代码最少修改,甚至无需修改,即可实现NVIDIA的消费级GPU的资源管理。从而克服了应用NVIDIA消费级GPU进行深度学习计算的非商业机构和科研机构经常出现GPU资源管理困难的问题。采用本发明所述方法,既可以将单张算强劲的GPU拆分让多人使用,也可以将多张GPU合为一个管理单位,让需要更强算力的应用得到受益。
附图说明
[0031] 图1是现有技术中GPU架构图。
[0032] 图2是现有技术中CUDA计算框架构图。
[0033] 图3是本实施例显存分配管理的流程图,其中虚线为现有技术中显存调用流程。
[0034] 图4是本实施例流处理器分配管理的流程图,其中虚线为现有技术中流处理器调用流程。

具体实施方式

[0035] 下面结合实施例及附图对本发明作进一步详细的描述,但本发明的实施方式不限于此。
[0036] 实施例
[0037] 如图1所示,目前的GPU硬件架构主要包括全局显存和流处理器,这也是本发明需要管理的两大类资源,流处理器内又包括诸如共享内存、寄存器、ALU等结构。
[0038] 参见图2所示的目前的CUDA程序库的结构,最底层的是GPU的驱动程序。上层是CUDA运行时API和各种计算库的API,下一层是CUDA驱动API,这些都是用户能够直接调用的API,本发明要拦截的API主要位于CUDA运行时层。
[0039] 如图3、4所示,本实施例一种通过API截获对NVIDIA消费级GPU进行资源管理的方法,该方法通过拦截CUDA运行时API(CUDART)层的API cudaMalloc函数,来进行显存分配和流处理器分配管理。
[0040] 参见图3虚线所示,现有技术中显存分配过程具体步骤如下:
[0041] (1)在CUDA应用程序中,CUDA用户代码通过调用一族cudaMalloc*函数,来指示CUDA运行时库进行显存分配。
[0042] (2)CUDA运行时库调用下层的CUDA驱动程序API,在CUDA驱动程序这一层,驱动程序会获取进程的CUDA上下文,并根据用户请求的容量进行显存分配。
[0043] (3)CUDA运行时库根据显存分配的结果成功与否,向调用cudaMalloc*函数的用户程序返回对应的显存分配成功信息,或者具体失败信息。
[0044] (4)用户程序对cudaMalloc*函数返回的结果进行处理,如果显存分配成功,则进行后面的CUDA计算步骤,如果显存分配失败,则进行对应的错误处理,或者直接终止CUDA程序。
[0045] 参见图3实线所示,本实施例通过API拦截对显存分配进行管理的过程具体步骤如下:
[0046] (1)在CUDA应用程序中,CUDA用户代码通过调用一族cudaMalloc*函数,来指示CUDA运行时库进行显存分配。
[0047] (2)此时,所有的cudaMalloc*函数都已被拦截,再用户调用cudaMalloc*函数的时候,控制流跳转到对应的cudaHookMalloc*函数中。
[0048] (3)控制流进入到cudaHookMalloc*函数后,cudaHookMalloc*函数根据预设好的显存分配规则和显存分配限额,对客户代码的此次显存分配请求进行是否符合显存分配规则的判断,然后查询显存分配限额还有没有剩余。
[0049] (4)若此次显存分配请求符合显存分配规则,且显存分配限额仍有剩余,则cudaHookMalloc*函数,会将来自CUDA客户代码的显存分配请求,转发到对应的CUDA运行时的cudaMalloc*函数中,并将cudaHookMalloc*函数返回的成功信息,或者失败信息,返回给CUDA客户代码。
[0050] (5)若此次显存分配请求不符合显存分配规则,或显存分配限额没有剩余,则cudaHookMalloc*函数会直接将显存分配失败的错误,返回给CUDA客户代码,由CUDA客户代码对显存分配失败的异常进行处理,或者直接结束CUDA程序。
[0051] 通过以上步骤即实现了按照预设好的显存分配规则和显存分配限额来进行显存分配的管理。
[0052] 参见图4虚线所示,现有技术中流处理器分配过程具体步骤如下:
[0053] (1)在CUDA应用程序中,CUDA用户代码通过编写CUDA核函数,并通过三对尖括号的语法,指定CUDA核运行的网格和线程块大小。
[0054] (2)NVCC工具在编译CUDA  C++代码时,将三对尖括号的语法,转化为对cudaLaunchKernel函数的调用,运行的网格和线程块大小,转化为cudaLaunchKernel函数的gridDim和blockDim参数。
[0055] (3)在执行到CUDA核函数的调用时,编译好的代码会调用cudaLaunchKernel函数,cudaLaunchKernel函数调用下层的CUDA驱动程序API,CUDA驱动程序指示显卡分配流处理器执行CUDA核函数。
[0056] 参见图4实线所示,本实施例通过API拦截对流处理器分配进行管理的过程具体步骤如下:
[0057] (1)在CUDA应用程序中,CUDA用户代码通过编写CUDA核函数,并通过三对尖括号的语法,指定CUDA核运行的网格和线程块大小。
[0058] (2)NVCC工具在编译CUDA  C++代码时,将三对尖括号的语法,转化为对cudaLaunchKernel函数的调用,运行的网格和线程块大小,转化为cudaLaunchKernel函数的gridDim和blockDim参数。
[0059] (3)在执行到CUDA核函数的调用时,编译好的代码会调用cudaLaunchKernel函数,此时,控制流跳转到cudaHookLaunchKernel函数中。
[0060] (4)在cudaHookLaunchKernel函数中,程序根据预先设置好的流处理器分配规则,判断此次分配请求是否符合流处理器分配规则,若不符合,则向用户代码返回启动核函数失败的错误,让CUDA用户代码自行处理错误或终止程序。
[0061] 针对上述方法,本实施例在windows下完成了基础的实现,windows下采用的动态共享库属于PE文件格式,具体的扩展名为.dll,因此采用由Microsoft开发的开源API拦截程序库Detours(https://github.com/microsoft/Detours)作为API拦截技术。具体实施方案如下:
[0062] (1)使用Detours前,必须确保源程序对CUDA库的调用是通过动态链接,即加载dll的方式进行,如果是静态链接,在源程序编译好,进行链接时,将会生成一份私有的代码,加入到程序的可执行文件中,由于加载时没有重定位这一步,API拦截将无法工作。
[0063] (2)本方法通过一个独立的程序启动器,来代理启动CUDA客户程序,在启动启动器的时候,通过命令行参数,传递CUDA客户程序的路径。
[0064] (3)程序启动器启动后,通过调用Detour库的函数DetourCreateProcessWithDllEx,将CUDA拦截dll注入到CUDA客户程序内,并启动CUDA客户程序进程。
[0065] (4)启动CUDA客户程序进程后,windows的dll加载机制随后会CUDA调用拦截dll内的dllmain函数,在dllmain函数中,会调用DetourAttach函数,此函数将一个无条件跳转指令插入到目标函数最前面,达到API拦截的目的。
[0066] (5)注意在编写拦截dll代码的时候,需要显式地用关键字__declspec(dllimport)向MSVC告知此拦截函数是通过dll共享导入的。否则,MSVC将会对此函数生成模块内部的调用版本,在拦截dll中调用Detours的拦截函数虽然返回成功,但只能在此模块内跳转到目标函数,在源程序中的函数调用并没有被拦截。
[0067] 本发明通过API调用拦截来对NVIDIA消费级GPU进行资源管理,使消费级GPU更能满足深度学习计算的使用要求,无需增加非商业机构和科研机构的使用成本。
[0068] 在本发明实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以是两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。
[0069] 所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个存储介质中。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分,或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(ROM,Read-Only Memory)、磁碟或者光盘等各种可以存储程序代码的介质。
[0070] 以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到各种等效的修改或替换,这些修改或替换都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应以权利要求的保护范围为准。
高效检索全球专利

专利汇是专利免费检索,专利查询,专利分析-国家发明专利查询检索分析平台,是提供专利分析,专利查询,专利检索等数据服务功能的知识产权数据服务商。

我们的产品包含105个国家的1.26亿组数据,免费查、免费专利分析。

申请试用

分析报告

专利汇分析报告产品可以对行业情报数据进行梳理分析,涉及维度包括行业专利基本状况分析、地域分析、技术分析、发明人分析、申请人分析、专利权人分析、失效分析、核心专利分析、法律分析、研发重点分析、企业专利处境分析、技术处境分析、专利寿命分析、企业定位分析、引证分析等超过60个分析角度,系统通过AI智能系统对图表进行解读,只需1分钟,一键生成行业专利分析报告。

申请试用

QQ群二维码
意见反馈