簡體   English   中英

在OpenCl中模擬動態內存分配

[英]simulating dynamic memory allocation in OpenCl

我遇到了一個使我瘋狂的問題。 我需要在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類型的大型數組,如下所示:

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]);
}   

運行程序時遇到以下錯誤:

" %27 = load i32 addrspace(1)* %26, align 4, !tbaa !17
Illegal pointer which is not from a valid memory space.
Aborting..."

您能幫我解決這個問題嗎? 我還發現,如果xx只有10個元素而不是100個元素,則代碼效果很好!

編輯:最簡單的解決方案:在malloc之前將填充值添加到'size',以便所有結構類型(其大小小於max-padding)都收到必要的對齊條件。

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字節的struct,那么即使現在一個int也需要64字節的malloc大小。 也許您可以在每個線程本地保存該值,以使用剩余的未使用區域。

因此,它不會產生對齊錯誤,並且對於那些沒有對齊錯誤的用戶,可能會更快地工作。

float3本機也需要16個字節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM