Можем ли мы скопировать "нормальную" память GPU в "унифицированную" память?

У нас есть две памяти GPU, одна выделена cuMalloc как обычная память устройства, другой выделяется с cuMallocManaged как единая память. Можно ли копировать между ними? и если мы используем драйвер API, какое направление я должен использовать?

float* normalMem, unifiedMem;
cuMalloc(&normalMem, 100);
cuMallocManaged(&unifiedMem, 100);
cuMemcpyD2D(unifiedMem, normalMem, 100); // ? D2D? or D2H? or else?

1 ответ

Да, вы можете. Посмотрите на следующий код, например.

  • Он объявил нормальный указатель управляемый указатель и указатель хоста все они из 100 float,
  • Затем он инициализирует значения в указателе хоста, а затем копирует значения с помощью cudaMemCpy в обычный указатель.
  • Значения теперь копируются в управляемый указатель
  • Управляемый указатель используется в ядре, чтобы показать, что значения были скопированы из двух буферов.

Я думаю, что код довольно понятен

__global__ 
void test(float* d_ptr){
    for(int i=0;i<100;i++)
        printf("%f \n",d_ptr[i]);
    printf("\n");
}

////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{

    size_t size = sizeof(float)*100;
    float* h_p =(float*) malloc(size);
    float* d_p, dm_p ; 
    cudaMalloc(&d_p,size);
    cudaMallocManaged(&dm_p,size);

    for(int i=0;i<100;i++)
        h_p[i]=2*(float)i;

    cudaMemcpy(d_p,h_p,size,cudaMemcpyHostToDevice);

    cudaDeviceSynchronize();

    cudaMemcpy(dm_p,d_p,size,cudaMemcpyDeviceToDevice);

    cudaDeviceSynchronize();

    test<<<1,1>>>(dm_p);

    cudaDeviceSynchronize();

    cudaFree(dm_p);
    cudaFree(d_p);
    free(h_p);
    return 0;
}

Не забудьте прочитать правила доступа к Единой памяти.

Другие вопросы по тегам