首页 文章

如何管理CUDA内存?

提问于
浏览
24

当我运行仅分配少量全局内存(低于20 M)的CUDA程序时,出现“内存不足”错误 . (从其他人的帖子中,我认为问题与内存碎片有关)我试着理解这个问题,并意识到我有几个与CUDA内存管理有关的问题 .

  • CUDA中是否有虚拟内存概念?

  • 如果只允许一个内核同时在CUDA上运行,在终止后,它使用或分配的所有内存都将被释放?如果没有,这些内存何时免费发布?

  • 如果允许在CUDA上运行多个内核,他们如何确保他们使用的内存不重叠?

谁能帮我回答这些问题?谢谢

编辑1:操作系统:x86_64 GNU / Linux CUDA版本:4.0设备:Geforce 200,它是连接到机器的GPUS之一,我不认为它是显示设备 .

编辑2:以下是我做了一些研究后得到的结果 . 随意纠正我 .

  • CUDA将为每个主机线程创建一个上下文 . 此上下文将保留诸如内存的哪一部分(预先分配的内存或动态分配的内存)等信息已保留给此应用程序,以便其他应用程序无法写入该应用程序 . 当此应用程序终止(不是内核)时,将释放这部分内存 .

  • CUDA内存由链接列表维护 . 当应用程序需要分配内存时,它将通过此链接列表查看是否有可用于分配的连续内存块 . 如果找不到这样的块,即使总可用内存大小大于请求的内存,“内存不足”错误也会向用户报告 . 这就是与内存碎片有关的问题 .

  • cuMemGetInfo将告诉您有多少可用内存,但不一定是由于内存碎片而可以在最大分配中分配多少内存 .

  • 在Vista平台(WDDM)上,GPU内存虚拟化是可行的 . 也就是说,多个应用程序几乎可以分配整个GPU内存,WDDM将管理交换数据到主内存 .

新问题:1 . 如果在应用程序终止后上下文中保留的内存将完全释放,则不应存在内存碎片 . 内存中必须留有某种数据 . 2.有没有办法重构GPU内存?

2 回答

  • 4

    代码在运行时可用的设备内存基本上计算为

    Free memory =   total memory 
                  - display driver reservations 
                  - CUDA driver reservations
                  - CUDA context static allocations (local memory, constant memory, device code)
                  - CUDA context runtime heap (in kernel allocations, recursive call stack, printf buffer, only on Fermi and newer GPUs)
                  - CUDA context user allocations (global memory, textures)
    

    如果您收到内存不足消息,那么在您的用户代码尝试在GPU中获取内存之前,前三项中的一个或多个可能正在消耗大部分GPU内存 . 如果您已经指出,如果您没有在显示器GPU上运行,那么上下文静态分配是您问题的最可能来源 . CUDA通过在设备上 Build 上下文时预先分配上下文所需的所有内存来工作 . 有很多东西可以分配来支持上下文,但上下文中单个最大的消费者是本地内存 . 对于设备上的每个多进程,运行时必须保留上下文中任何内核将使用的最大本地内存量,以满足每个多处理器可以同时运行的最大线程数 . 如果在具有大量多处理器的设备上加载本地内存繁重的内核,则可能会遇到数百Mb的内存 .

    查看可能发生的事情的最佳方法是编写一个没有设备代码的主机程序,该程序代码 Build 上下文并调用 cudaMemGetInfo . 这将显示设备具有多少内存以及最小的上下文开销 . 然后运行有问题的代码,在第一次 cudaMalloc 调用之前添加相同的 cudaMemGetInfo 调用,然后将为您提供上下文所使用的内存量 . 这可能会让你掌握内存的来源 . 如果您在第一次 cudaMalloc 呼叫失败时,碎片化是不太可能的问题 .

  • 25
    • GPU片外存储器在全局,本地和常量存储器中分离 . 这三种内存类型是虚拟内存概念 . 全局内存对所有线程都是免费的,本地只用于一个线程(主要用于寄存器溢出),而常量内存是高速缓存的全局内存(只能从主机代码写入) . 请参阅CUDA C编程指南中的5.3.2 .

    • 编辑:删除

    • 通过分配的内存 cudaMalloc 永远不会重叠 . 对于内核在运行时分配的内存应该是足够的可用内存 . 如果你内存不足并尝试启动内核(只是猜测一下),你应该收到"unknown error"错误消息 . 驱动程序比无法启动和/或执行内核 .

相关问题