我已经使用OpenCL成功实现了数字下变换器。在实现插值部分时,我只能设置146的最大因子。任何一个都会导致程序崩溃并引发错误代码CL_INVALID_MEM_OBJECT -38
。使用太多内存的OpenCL程序
对于那些不知道的人来说,插值是一种在已知数据点范围内构建新数据点的方法。 DDC或数字下变频器用于在尝试通过重构滤波器重建数据点时增加或减少采样率。
请注意,我正在使用的文件是1.75Mb的wav文件作为输入。它的采样频率为44100,我的目标是以48000采样(蓝光质量)。这导致160/147的插值/抽取因子。但是,超过146的任何插值因素会导致驱动程序和程序崩溃,并且如上所示抛出-38的错误。
我认为问题在于我创建了cl_mem
缓冲区。我大概有7个,这里是他们如何初始化和使用。假设P为3且Q是2,而项数是918222个样品:
input = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
num_items * sizeof(float),
NULL,
&status);
output = clCreateBuffer(
context,
CL_MEM_WRITE_ONLY,
num_items * P * sizeof(float),
NULL,
&status);
//Lowpass kernel parameters
inputForLowpass = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
num_items * P * sizeof(float),
NULL,
&status);
outputFromLowpass = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
num_items * P * sizeof(float),
NULL,
&status);
//Decimate kernel parameters
inputForDecimate = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
num_items * P * sizeof(float),
NULL,
&status);
outputFromDecimate = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
(int)(num_items * (P*1.0/Q) * sizeof(float)),
NULL,
&status);
//numOfCoefficients for number of taps
coeff = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
numOfCoefficients * sizeof(float),
NULL,
&status);
我用在Visual Studio中存储器调试器来找到程序使用602Mb(为160的内插因子之前它崩溃它用于围绕120MB。为3的因素,仍然很多!)我怎么能把这个下降?我是否以不正确的方式使用缓冲区?
最重要的是,我有三个主机代码中的其他内存分配。 'Array'只是保存wav文件中的值,而OutputData和OutputData2分别存储来自过滤输入和抽取输入的值。
Array = (float*)malloc(num_items * sizeof(float));
OutputData = (float*)malloc(num_items * P * sizeof(float));
OutputData2 = (float*)malloc((int)(num_items * (P*1.0/Q) * sizeof(float)));
以下是Visual Studio中P = 3时的内存使用情况(数组增加3的大小)。
这里就是我得到的-38码writeBuffers之一。
status = clEnqueueWriteBuffer(
cmdQueue,
inputForLowpass,
CL_FALSE,
0,
num_items * P * sizeof(float),
OutputData,
0,
NULL,
NULL);
printf("Input enqueueWriteBuffer for Lowpass Kernel status: %i \n", status);
这里是低通内核:
__kernel void lowpass(__global float *Array, __global float *coefficients, __global float *Output, __const int numOfCoefficients) {
int globalId = get_global_id(0);
float sum=0.0f;
int min_i= max((numOfCoefficients-1),globalId)-(numOfCoefficients-1);
int max_i= min_i+numOfCoefficients;
for (int i=min_i; i< max_i; i++)
{
sum +=Array[i]*coefficients[globalId-i];
}
//sum = min(., (0.999969482421875));
//sum = max(sum, -1.0f);
Output[globalId]=sum;
}
EDIT发生 错误,因为缓冲区大小我分配有超过所使用的存储器的512Mb。这是我可以拥有的最大缓冲区大小。为了解决这个问题,我必须在我的代码中实现某种内存管理系统。也许一次使用8Mb缓冲区。
你能告诉我们你写入这些缓冲区的位置以及你调用内核的地方吗? (并且清理代码也可能是个好主意)'CL_INVALID_MEM_OBJECT'我认为不会被'clCreateBuffer'抛出。 – JavaProphet
@JavaProphet我已经添加了writeBuffer以及内核。它也为decimate内核抛出相同的错误。我会尝试添加发生错误时输出的日志消息。 – VedhaR