2016-01-13 36 views
2

據我所知,當我將一個結構或類傳遞給內核時,拷貝構造函數在主機端被調用,然後複製的對象被髮送到設備與memcpy。這裏有一個例子:在將對象傳遞給內核前防止拷貝構造函數

class Foo { 
    Foo(const Foo&) {std::cout << "Called before kernel execution";} 
}; 

__global__ void kernel(Foo foo) { } 

我可以以某種方式阻止稱爲複製構造函數,使CUDA memcpy對象直接設備內存?通過引用傳遞foo將不起作用,因爲它會混淆設備和主機內存。

+1

也許你應該給出一個更完整的例子來說明你正在嘗試做什麼(例如,顯示你正嘗試傳遞給內核的'foo'對象的設置)。如果你在主機上設置了這樣一個對象,你應該可以使用'cudaMemcpy'將它複製到設備上,而不用調用任何對象方法或構造函數。並且在cuda內核調用中無法使用傳遞引用,因此也許您的意思是傳遞指針。我建議使用傳遞指針,但對我來說還不清楚爲什麼這樣做不起作用。 –

+0

如果編譯器在將參數傳遞給三重V形圖時調用複製構造函數,我懷疑是否有辦法阻止它。要解決這個問題,你可以通過'cudaSetupArgument'和'cudaLaunch'自己編組參數來啓動'kernel'。但是,這些API可能會被棄用。 –

回答

1

看看託管內存,例如2013年會議上的these幻燈片。從本質上講,如果您編寫類來擴展CUDA類,並使用正確的內存分配,則可以通過引用傳遞,CUDA將處理內存管理。

+0

我想這會導致性能下降,但? –

+0

根據我的經驗,略有性能下降是值得的,但我主要處理複雜的對象,這些對象只能在程序中複製到設備上。如果您經常使用簡單的物體,結果可能會有所不同。 – icurays1

1

我的建議是通過指針傳遞foo

$ cat t1041.cu 
#include <stdio.h> 

class Foo { 
    public: 
    __host__ __device__ 
    void chirp() { printf("Hello!\n"); } 
    __host__ __device__ 
    Foo(const Foo&) {printf("Called copy constructor!\n");} 
    __host__ __device__ 
    Foo(){}; 
}; 


__global__ void kernel(Foo *foo) { 

    foo->chirp(); 
} 

int main(){ 

    Foo myfoo, *d_foo; 
    cudaMalloc(&d_foo, sizeof(Foo)); 
    cudaMemcpy(d_foo, &myfoo, sizeof(Foo), cudaMemcpyHostToDevice); 
    kernel<<<1,1>>>(d_foo); 
    cudaDeviceSynchronize(); 
} 

$ nvcc -o t1041 t1041.cu 
$ ./t1041 
Hello! 
$ 

你也可以使用託管內存,支持它,通過@ icurays1所建議的平臺。