Можем ли мы скопировать "нормальную" память 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;
}
Не забудьте прочитать правила доступа к Единой памяти.