2017-01-31 12 views
1

cudaは、カーネルの起動時に、割り当てられたすべての管理対象メモリをブロックしてGPUに転送しますか?私はumaと遊んで、奇妙な結果を得ました。私の視点では少なくとも。Cuda、統合メモリ、データ転送

私は2つの配列を作成し、Aをカーネルに送りますが、Bはカーネル呼び出しの手で触れられませんが、アクセスすることはできません。

0 0 0 here1 0 here2 after1:プログラムはちょうど私が私がb[0] = 1;行をコメントアウトした場合のコードは正常に動作B.

0 0 0 here1

をタッチするとクラッシュします1 after2

どうしてですか?

__global__ void kernel(int* t) 
{ 
    t[0]++; 

} 


int main() 
{ 
    int* a; 
    int* b; 


    std::cout << cudaMallocManaged(&a,sizeof(int)*100) << std::endl; 
    std::cout << cudaMallocManaged(&b,sizeof(int)*100) << std::endl; 

    std::cout << b[0] << std::endl; 

    kernel<<<1,1,0,0>>>(a); 

    std::cout << "here1" << std::endl; 
    b[0] = 1; 
    std::cout << "after1" << std::endl; 

    cudaDeviceSynchronize(); 


    std::cout << b[0] << std::endl; 

    std::cout << "here2" << std::endl; 
    std::cout << a[0] << std::endl; 
    std::cout << "after2" << std::endl; 




    return 0; 
} 

答えて

2

は、CUDAは何とか阻止し、カーネルが起動されたとき にGPUを割り当てられたすべての管理するメモリを転送していますか?

はい、ご使用のデバイスの計算能力が6.0未満です。

これらのデバイスでは、管理対象メモリは、カーネルが起動する前にすべての管理対象メモリをGPUにコピーし、すべての管理対象メモリを同期してホストにコピーします。そのタイムスパンの間に、ホストwill lead to a segmentation faultから管理対象メモリにアクセスします。

与えられたカーネルのコピー先のメモリをattaching it to a stream using cudaStreamAttachMemAsync()で特定し、そのストリームにカーネルを起動することができます。