Pracuję nad projektem, w którym potrzebuję mojego urządzenia CUDA do wykonywania obliczeń na strukturze zawierającej wskaźniki.Kopiowanie struktury zawierającej wskaźniki do urządzenia CUDA
typedef struct StructA {
int* arr;
} StructA;
Kiedy przydzielić pamięci dla struktury, a następnie skopiować go na urządzenie będzie kopiować tylko struct a nie zawartość wskaźnika. Obecnie pracuję nad tym, najpierw przydzielając wskaźnik, a następnie ustawiając strukturę hosta do korzystania z tego nowego wskaźnika (który znajduje się na GPU). Poniższy przykładowy kod opisuje to podejście za pomocą struct z góry:
#define N 10
int main() {
int h_arr[N] = {1,2,3,4,5,6,7,8,9,10};
StructA *h_a = (StructA*)malloc(sizeof(StructA));
StructA *d_a;
int *d_arr;
// 1. Allocate device struct.
cudaMalloc((void**) &d_a, sizeof(StructA));
// 2. Allocate device pointer.
cudaMalloc((void**) &(d_arr), sizeof(int)*N);
// 3. Copy pointer content from host to device.
cudaMemcpy(d_arr, h_arr, sizeof(int)*N, cudaMemcpyHostToDevice);
// 4. Point to device pointer in host struct.
h_a->arr = d_arr;
// 5. Copy struct from host to device.
cudaMemcpy(d_a, h_a, sizeof(StructA), cudaMemcpyHostToDevice);
// 6. Call kernel.
kernel<<<N,1>>>(d_a);
// 7. Copy struct from device to host.
cudaMemcpy(h_a, d_a, sizeof(StructA), cudaMemcpyDeviceToHost);
// 8. Copy pointer from device to host.
cudaMemcpy(h_arr, d_arr, sizeof(int)*N, cudaMemcpyDeviceToHost);
// 9. Point to host pointer in host struct.
h_a->arr = h_arr;
}
Moje pytanie brzmi: Czy w ten sposób to zrobić?
Wygląda na to, że mam dużo pracy i przypominam, że jest to bardzo prosta struktura. Jeśli moja struktura zawiera wiele wskaźników lub struktur z samymi wskaźnikami, kod przydzielania i kopiowania będzie dość obszerny i mylący.
Kroki 7 i 9 są zbędne, ale poza tym tak właśnie jest.Zgodnie z poniższą odpowiedzią, najlepsze rozwiązanie zapewnia unikanie złożonych struktur danych opartych na wskaźnikach na GPU. Wydajność na GPU jest gorsza, a interfejsy API naprawdę nie są do tego przystosowane. – talonmies
Widzę, że krok 7 jest zbędny, ale dlaczego krok 9? –
oraz 'h_a' jest (lub powinno być)" obrazem "struktury urządzenia przechowywanej w pamięci hosta. Przypisanie go do przechowywania wskaźnika w pamięci hosta jest prawdopodobnie pewną kombinacją złej praktyki/zła/pamięci wycieku pamięci w zależności od tego, jakie są twoje prawdziwe intencje. Po skopiowaniu zawartości 'd_a' z powrotem do' h_a', masz "pełne koło" i jesteś z powrotem tam, gdzie zaczynałeś. – talonmies