2017-05-19 7 views
1

私はCUDAにはかなり新しく、オブジェクトのメモリ管理に関する質問があります。私はデバイスにデータをロードするオブジェクト関数を持っていて、別のオブジェクト関数が呼び出されると計算が実行されます。異なる機能でのcudaデバイス変数の割り当てと使用

私はNVIDIAプログラミングガイドのいくつかの部分を読んでいますが、いくつかのSOの質問をしていますが、データのコピーとコンピューティングは単一の機能であり、複数の機能は必要ありません。

さらに仕様: データは1回読み込まれます。コンパイル時にデータサイズがわからないので、動的割り当てが必要です。現在のデバイスのコンピューティング機能は2.1(すぐに6.1に更新されます)です。

最初の関数でデータをコピーし、別の関数でデータを使用したいとします。たとえば:

__constant__ int dev_size; 
__device__ float* dev_data; //<- not sure about this 

/* kernel */ 
__global__ void computeSomething(float* dev_output) 
{ 
    int idx = blockIdx.x * blockDim.x + threadIdx.x; 
    if (idx < dev_size) 
    { 
     dev_output[idx] = dev_data[idx]*100; // some computation; 
    } 
} 

// function 1 
void OBJECT::copyVolumeToGPU(int size, float* data) 
{ 
    cudaMalloc(&dev_data, size * sizeof(float)); 
    cudaMemcpy(dev_data, data, size * sizeof(float), cudaMemcpyHostToDevice); 
    cudaMemcpyToSymbol(dev_size, size, sizeof(int)); 
} 

// function 2 
void OBJECT::computeSmthOnDevice(int size) 
{ 
    // allocate output array 
    auto host_output = new float[size]; 
    float* dev_output; 
    cudaMalloc(&dev_output, size * sizeof(float)); 

    int block = 256; 
    int grid = ceil(size/block); 
    computeSomething<<<grid,block>>>(dev_output); 

    cudaMemcpy(host_output, dev_data, size * sizeof(float), cudaMemcpyDeviceToHost); 

    /* ... do something with output ... */ 

    delete[] host_output; 
    cudaFree(dev_output); 
} 

gpuErrChkはこのように行われる:https://stackoverflow.com/a/14038590/3921660をが、この例では省略します。

__device__ポインタ(__device__ float* dev_data;など)を使用してデータをコピーできますか?

+0

コードで意味することを試してみることができますか?あなたがここで尋ねようとしていることを理解することは非常に容易ではないからです。 – talonmies

+0

ようこそ。あなたの質問を改善するためのこの[how-to-ask](http://stackoverflow.com/help/how-to-ask)をお読みください。 – thewaywewere

答えて

2

一般的に、あなたのアイデアが実行可能であるが、この:

cudaMalloc(&dev_data, size * sizeof(float)); 

は法的ではありません。ホストコードの__device__項目のアドレスを取得することは合法ではありません。コンパイル時にサイズを知っている場合、最も簡単な方法は、これを静的な割り当てに変換することです。 「一時的なものであり、ホストコード内の典型的なデバイスのポインタにcudaMallocを使用することを含む

__device__ float dev_data[1000]; 

本当にこの動的に割り当てられた__device__ポインタにしたい場合は、あなたがそのような説明hereような方法を使用する必要があります、 "__device__ポインタへの"一時的 "ポインタをcudaMemcpyToSymbol経由でコピーします。そして、その特定の割り当てとの間でデータをコピーする場合は、cudaMemcpyを使用して、cudaMemcpyのホストコードからのポインタに/から使用します。

ある関数から次の関数または次のカーネルにデータを "通信"する目的で、cudaMemcpyから動的に割り当てられたポインタを使用するだけの理由はありません。あなたがそれを必要とするどこにでも。通常のグローバルポインタのように、それを必要とする任意のホスト関数にグローバル変数で渡すことさえできます。しかし、カーネルの場合、カーネル引数を介してカーネルにそのようなグローバルポインタを渡す必要があります。

+0

私はあなたの提案を実装しようとしています。最後の文章を説明できますか?私はあなたが "コマンドライン引数を介して渡す"という意味を得ていませんでした。 – KabCode

+0

申し訳ありませんが、それは言葉の悪い選択でした。私は編集しました。ポインタを明示的にカーネルの引数として渡すことを意図しています。 –

関連する問題