que estoy trabajando en un proyecto donde tengo mi dispositivo CUDA para hacer cálculos en una estructura que contiene punteros.Copiar una estructura que contiene punteros a dispositivo CUDA
typedef struct StructA {
int* arr;
} StructA;
Cuando asignar memoria para la estructura y luego copiarlo en el dispositivo, sólo se copiará la estructura y no el contenido del puntero. En este momento estoy trabajando en esto asignando el puntero primero, luego establezco la estructura del host para usar ese nuevo puntero (que reside en la GPU). El ejemplo de código siguiente describe este enfoque utilizando la estructura de arriba:
#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;
}
Mi pregunta es: Es esta la manera de hacerlo?
Parece que una gran cantidad de trabajo, y les recuerdo que esta es una estructura muy simple. Si mi estructura contiene muchos punteros o estructuras con punteros, el código de asignación y copia será bastante extenso y confuso.
Pasos 7 y 9 son redundantes, pero por lo demás es más o menos como está.Como dice la respuesta a continuación, lo mejor es evitar estructuras de datos complejas basadas en punteros en la GPU. El rendimiento en la GPU es peor, y las API realmente no están diseñadas para eso. – talonmies
Veo que el paso 7 es redundante, pero ¿por qué el paso 9? –
bien 'h_a' es (o debería ser) una" imagen "de la estructura del dispositivo retenida en la memoria del host. Asignarlo para que contenga un puntero en la memoria del host es probablemente una combinación de mala práctica/error/pérdida de memoria del dispositivo dependiendo de cuáles sean sus verdaderas intenciones. Después de haber copiado el contenido de 'd_a' de nuevo a' h_a', has "completado el círculo" y estás de vuelta desde donde comenzaste. – talonmies