Memory OpenCl中动态内存分配的模拟
我遇到了一个让我发疯的问题。 我需要在OpenCl内核中模拟动态内存分配。在这方面,我在*.cl文件中定义了以下malloc函数:Memory OpenCl中动态内存分配的模拟,memory,dynamic,malloc,opencl,c99,Memory,Dynamic,Malloc,Opencl,C99,我遇到了一个让我发疯的问题。 我需要在OpenCl内核中模拟动态内存分配。在这方面,我在*.cl文件中定义了以下malloc函数: __global void* malloc(size_t size, __global byte *heap, __global uint *next) { uint index = atomic_add(next, size); return heap+index; } 在主机程序中,我动态地为这个虚拟堆指定了一个大型cl_uchar类型的数组,如下所
__global void* malloc(size_t size, __global byte *heap, __global uint *next)
{
uint index = atomic_add(next, size);
return heap+index;
}
在主机程序中,我动态地为这个虚拟堆指定了一个大型cl_uchar类型的数组,如下所示:
int MAX_NUM_OF_HEADERS_PROCESSED_IN_PARALLEL = 1000;
cl_uchar* heap = new cl_byte[1000000];
cl_uint *next = new cl_uint;
*next = 0;
cl_uint * test_result =
new cl_uint[MAX_NUM_OF_HEADERS_PROCESSED_IN_PARALLEL];
cl_mem memory[3]= { 0, 0, 0};
cl_int error;
memory[0] = clCreateBuffer(GPU_context,
CL_MEM_READ_WRITE, sizeof(cl_uchar) * MAX_HEAP_SIZE, NULL,
NULL);
memory[1] = clCreateBuffer(GPU_context, CL_MEM_READ_WRITE, sizeof(cl_uint), NULL,
&error);
memory[2] = clCreateBuffer(GPU_context, CL_MEM_READ_WRITE,
sizeof(cl_uint) * MAX_NUM_OF_HEADERS_PROCESSED_IN_PARALLEL, NULL,
&error);
clEnqueueWriteBuffer(command_queue, memory[0], CL_TRUE, 0,
sizeof(cl_uchar) * MAX_HEAP_SIZE, heap, 0, NULL, NULL);
clEnqueueWriteBuffer(command_queue, memory[1], CL_TRUE, 0, sizeof(cl_uint),
next, 0, NULL, NULL);
error = 0;
error |= clSetKernelArg(kernel, 0, sizeof(cl_mem), &memory[0]);
error |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &memory[1]);
error |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &memory[2]);
size_t globalWorkSize[1] = { MAX_NUM_OF_HEADERS_PROCESSED_IN_PARALLEL };
size_t localWorkSize[1] = { 1 };
error = 0;
error = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
globalWorkSize, localWorkSize, 0, NULL, NULL);
我还有以下内核:
__kernel void packet_routing2(__global byte* heap_, __global uint* next, __global uint* test_result){
int gid = get_global_id(0);
__global uint*xx[100];
for ( int i = 0 ; i < 100; i ++)
{
xx[i] = (__global uint*) malloc(sizeof(uint),heap_,next);
*xx[i] = i*gid;
result[gid] = *(xx[0]);
}
你能帮我解决这个问题吗。我还发现,如果xx只有10个元素,而不是100个元素,那么代码工作得很好 编辑:最简单的解决方案:在malloc之前向“size”添加一个填充值,以便所有结构类型(大小小于最大填充)接收必要的对齐条件 0=内存中的结构示意图 *=堆 _=填充
***000_____*****0000____****0_______****00000___*****0000000_*******00______***
|
v
save this unused padded memory space in its thread to use later.
第一个/起始地址值必须满足最大对齐要求,这一点很重要。如果有一个长度为256字节的结构,它应该有256字节的倍数开始
struct size malloc size minimum 'next' value (address, not offset)
1-4 4 multiple of 4
5-8 8 multiple of 8
9-16 16 multiple of 16
17-32 32 32*k
33-64 64 64*k
如果有64字节的结构,即使是int现在也需要64字节的malloc大小。也许您可以在每个线程本地保存该值,以使用剩余的未使用区域
因此,它不会给出对齐错误,对于那些没有对齐错误的,它可能工作得更快
此外,float3本机需要16字节。编辑:最简单的解决方案:在malloc之前向“size”添加一个填充值,以便所有结构类型(大小小于最大填充)接收必要的对齐条件 0=内存中的结构示意图 *=堆 _=填充
***000_____*****0000____****0_______****00000___*****0000000_*******00______***
|
v
save this unused padded memory space in its thread to use later.
第一个/起始地址值必须满足最大对齐要求,这一点很重要。如果有一个长度为256字节的结构,它应该有256字节的倍数开始
struct size malloc size minimum 'next' value (address, not offset)
1-4 4 multiple of 4
5-8 8 multiple of 8
9-16 16 multiple of 16
17-32 32 32*k
33-64 64 64*k
如果有64字节的结构,即使是int现在也需要64字节的malloc大小。也许您可以在每个线程本地保存该值,以使用剩余的未使用区域
因此,它不会给出对齐错误,对于那些没有对齐错误的,它可能工作得更快
另外,float3本机需要16字节。@AlirezaMontazeriGh我添加了一些内容到b)非常感谢@HuseyinTugrulBuyukisik@AlirezaMontazeriGh没问题。但是,正如您所看到的,这并没有跨越多个图形卡。您可以使用异步加载/stora指令保存大结构,这样驱动程序可能会优化访问模式。@AlirezaMontazeriGh我在b)中添加了一些内容。非常感谢@HuseyinTugrulBuyukisik。@AlirezaMontazeriGh没问题。但是,正如您所看到的,这并没有跨越多个图形卡。您可以使用异步加载/存储指令来保存大型结构,这样驱动程序可能会优化访问模式。