2016-10-27 3 views
1

cudaMalloc()으로 할당 된 엔티티를 확인하는 가장 쉬운 방법은 현재 GPU 장치에 있습니까? 한 번만 호출하고 종료하면 아무런 메모리 누수가 없다 (cuda-memcheck를 통해 검사 됨), 여러 번 호출되면 메모리 풋 프린트가 더 커지고 커지도록 함수 내부에서 메모리 누수를 찾고 싶습니다.GPU 메모리에 현재 상주하는 엔티티 확인

Nsight 비주얼 프로파일 러는 내가 묻는 것에 너무 복잡해 보이고 cuda-memcheck는 누출을 발견하지 못합니다!

+2

CUDA 런타임 API는 현재 할당 목록을 가져 오는 메소드를 제공하지 않습니다. 이것이 당신이 원하는 것이라면, 당신을 위해 몇몇 사용자 관리 테이블에 이것을 등록하는 래퍼 함수 ('cudaMalloc'을 위해)를 만들어야 할 것입니다. 이 질문은 저에게 X-Y 문제처럼 보입니다. 실제 문제를 자세히 설명하면 도움이 될 수 있습니다. 예를 들어 이것은 호스트 함수 또는 호출중인 장치 함수입니까? 메모리 풋 프린트를 결정하기 위해 어떤 방법을 사용하고 있습니까? 문제를 보여주는 [mcve]를 제공 할 수 있다면 더 좋습니다. –

답변

2

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에서의 메모리 관리는 예측할 수있는 정도로 예측할 수 없으며, 주어진 메모리 사용량에 따라 메모리 누수를 진단 할 때주의해야합니다. 즉시. 자세한 내용은 this question을 참조하십시오.

관련 문제