2016-10-27 18 views
1

cudaMalloc()で割り当てられたエンティティを確認する最も簡単な方法は、現在GPUデバイスに存在しますか?私は関数内でメモリリークを見つけたいと思います。一度だけ呼び出されて終了すると、メモリリークはありません(cuda-memcheckでチェックされます)。しかし、複数回呼び出されると、メモリフットプリントはますます大きくなります。GPUメモリに現在存在するエンティティを確認する

Nsight Visual Profilerは私が尋ねるものにはあまりにも複雑すぎて、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を参照してください。

関連する問題