据我所知,我们可以在内核内存中分配一个固定内存区域。 (来自KGPU)
然后,在固定内存中分配Linux内核数据并传输到GPU。
但问题是linux内核数据应该安排为数组。
今天,一个树是一个案例。
我已经尝试将其从固定内存传递到GPU。
但是当节点访问下一个节点时,发生了内存访问错误。
我想知道统一内存可以在内核内存中分配为固定内存区吗?
因此,可以在统一内存区域中构建树,并由GPU使用,而不使用其他运行时API,如cudaMallocMaganed
。
或者统一内存必须只使用cudaMallocMaganed
?
答案 0 :(得分:1)
但是当节点访问下一个节点时,发生了内存访问错误。
这只是意味着您的代码中存在错误。
或者统一内存必须只使用cudaMallocManaged?
目前,访问统一内存功能的唯一方法是使用托管分配器。对于动态分配,即cudaMallocManaged()
。对于静态分配,它是通过__managed__
关键字。
The programming guide有其他信息。
回应下面的评论,这是一个简单的工作示例,使用固定内存创建单链表,并在设备代码中遍历该列表:
$ cat t1115.cu
#include <stdio.h>
#define NUM_ELE 5
struct ListElem{
int id;
bool last;
ListElem *next;
};
__global__ void test_kernel(ListElem *list){
int count = 0;
while (!(list->last)){
printf("List element %d has id %d\n", count++, list->id);
list = list->next;}
printf("List element %d is the last item in the list\n", count);
}
int main(){
ListElem *h_list, *my_list;
cudaHostAlloc(&h_list, sizeof(ListElem), cudaHostAllocDefault);
my_list = h_list;
for (int i = 0; i < NUM_ELE-1; i++){
my_list->id = i+101;
my_list->last = false;
cudaHostAlloc(&(my_list->next), sizeof(ListElem), cudaHostAllocDefault);
my_list = my_list->next;}
my_list->last = true;
test_kernel<<<1,1>>>(h_list);
cudaDeviceSynchronize();
}
$ nvcc -o t1115 t1115.cu
$ cuda-memcheck ./t1115
========= CUDA-MEMCHECK
List element 0 has id 101
List element 1 has id 102
List element 2 has id 103
List element 3 has id 104
List element 4 is the last item in the list
========= ERROR SUMMARY: 0 errors
$
请注意,为了简洁起见,我在此示例中省略了proper CUDA error checking(尽管使用cuda-memcheck
运行代码表明没有CUDA运行时错误),但我建议它在您遇到CUDA代码时遇到问题。另请注意,此示例假定为proper UVA environment。