我已經使用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