检查当前驻留在GPU内存中的实体



检查使用cudaMalloc()分配的实体(及其大小)当前驻留在GPU设备上的最简单方法是什么?我想找到一个函数内部的内存泄漏,如果它只是调用一次并退出,没有内存泄漏(通过cuda-memcheck检查),但如果调用多次内存占用变得越来越大。

Nsight Visual Profiler对于我的要求来说似乎太复杂了,cuda-memcheck没有发现泄漏!

没有办法在CUDA api中做到这一点。如果你确实想这样做,你需要制作你自己的仪器系统来包装你的代码调用的CUDA内存分配/释放api。最简单的实现如下所示:

#include <iostream>
#include <vector>
#include <algorithm>
typedef std::pair<void*, size_t> mrecord;
struct mymemory
{
    std::vector<mrecord> mstack;
    mymemory() {};
    cudaError_t cudaMalloc(void** p, size_t sz);
    cudaError_t cudaFree(void* p);
    void print_stack();
};
cudaError_t mymemory::cudaMalloc(void** p, size_t sz)
{
    cudaError_t ret = ::cudaMalloc(p, sz);
    if (ret == cudaSuccess) {
       mstack.push_back(mrecord(*p,sz));
    }
    return ret;
};

cudaError_t mymemory::cudaFree(void* p)
{
    cudaError_t ret = ::cudaFree(p);
    if (ret == cudaSuccess) {
        auto rit = std::find_if( mstack.begin(), mstack.end(),
                                 [&](const mrecord& r){ return r.first == p; } );
        if (rit != mstack.end()) {
            mstack.erase(rit);
        }
    }
    return ret;
};
void mymemory::print_stack()
{
    auto it = mstack.begin();
    for(; it != mstack.end(); ++it) {
        mrecord rec = *it;
        std::cout << rec.first << " : " << rec.second << std::endl;
    }
}

int main(void) 
{
    const int nallocs = 10;
    void* pointers[nallocs];
    mymemory mdebug;
    for(int i=0; i<nallocs; ++i) {
        mdebug.cudaMalloc(&pointers[i], 4<<i);
    }
    std::cout << "After Allocation" << std::endl;
    mdebug.print_stack();
    mdebug.cudaFree(pointers[1]);
    mdebug.cudaFree(pointers[7]);
    mdebug.cudaFree(pointers[8]);
    mdebug.cudaFree(0);
    std::cout << "After Deallocation" << std::endl;
    mdebug.print_stack();
    return 0;
}

[警告:只有非常轻微测试和需要c++ 11编译器支持]

执行如下操作:

~/SO$ nvcc -std=c++11 -g -arch=sm_52 instrumentation.cu 
~/SO$ ./a.out 
After Allocation
0x705e40000 : 4
0x705e40200 : 8
0x705e40400 : 16
0x705e40600 : 32
0x705e40800 : 64
0x705e40a00 : 128
0x705e40c00 : 256
0x705e40e00 : 512
0x705e41000 : 1024
0x705f40000 : 2048
After Deallocation
0x705e40000 : 4
0x705e40400 : 16
0x705e40600 : 32
0x705e40800 : 64
0x705e40a00 : 128
0x705e40c00 : 256
0x705f40000 : 2048

这可能足以了解哪些内存分配正在泄漏。但是要注意,GPU上的内存管理并不像你想象的那样可预测,当你仅仅根据设备在任何给定时刻报告的空闲内存量来诊断内存泄漏时,你需要小心。

相关内容

  • 没有找到相关文章

最新更新