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を参照してください。
CUDAランタイムAPIは、現在の割り当てのリストを取得するメソッドを提供しません。これが必要な場合は、ユーザ管理テーブルにこれらを登録するためのラッパー関数( 'cudaMalloc'用)を構築する必要があります。この質問は、私にとってX-Yの問題のように見えます。実際の問題をより詳しく説明すると、より良い助けになるかもしれません。例えば、これはあなたが呼んでいるホスト機能またはデバイス機能ですか?メモリフットプリントを決定するためにどのような方法を使用していますか?問題を示す[mcve]を提供できる場合はさらに優れています。 –