2016-07-28 2 views
1

OpenCL을 사용하여 Digital Down Converter를 성공적으로 구현했습니다. 보간 부분을 구현할 때 최대 계수를 146으로 설정할 수 있습니다. 더 이상 발생하면 프로그램이 중단되고 CL_INVALID_MEM_OBJECT -38의 오류 코드가 발생합니다.너무 많은 메모리를 사용하는 OpenCL 프로그램

모르는 사람들을 위해, 보간법은 알려진 데이터 범위의 범위 내에서 새로운 데이터 포인트를 구성하는 방법입니다. DDC 또는 디지털 다운 컨버터는 재구성 필터를 사용하여 데이터 포인트를 재구성하는 동안 샘플링 속도를 모두 높이거나 낮추는 데 사용됩니다.

내가 사용중인 파일은 입력으로 1.75Mb wav 파일입니다. 44100에서 샘플링되며 목표는 48000 (블루 레이 품질)으로 샘플링하는 것입니다. 결과적으로 보간/데시 메이션 계수는 160/147이됩니다. 그러나 146 이상의 모든 보간 인자가 드라이버와 프로그램을 충돌 시키며 위에 나온 것처럼 -38에 대한 오류가 발생합니다.

나는 문제가 내가 cl_mem 버퍼를 만드는 곳에 있다고 생각한다. 나는 약 7 개를 가지고 있는데, 어떻게 초기화되고 사용되는지가 나와있다. 가정 P는 3이고 _ 개수가 918,222 샘플 중에 Q가 2 :

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); 
I 프로그램은 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))); 

다음은 비주얼 스튜디오에서 P = 3 (배열이 3 크기만큼 증가)의 메모리 사용량을 보여주는 이미지입니다.

enter image description here

는 여기가 -38 코드를 얻을 writeBuffers 중 하나입니다. 512MB의 메모리가 사용되는 동안 I가 할당 버퍼 크기 때문에 에러가 발생

__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 : 여기

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

는 저역 통과 커널이다. 그것은 내가 가질 수있는 버퍼의 최대 크기입니다. 이 문제를 해결하기 위해 필자는 코드에 일종의 메모리 관리 시스템을 구현해야합니다. 아마도 한 번에 8MB 버퍼를 사용하는 것입니다.

+0

버퍼에 쓸 위치와 커널 호출 위치를 보여줄 수 있습니까? CL_INVALID_MEM_OBJECT' 나는'clCreateBuffer'에 의해 던져지지 않는다고 생각합니다. – JavaProphet

+0

@JavaProphet 커널뿐만 아니라 writeBuffer도 추가했습니다. 또한 decimate 커널에 대해서도 같은 오류가 발생합니다. 오류가 발생할 때 출력되는 로그 메시지를 추가하려고합니다. – VedhaR

답변

0

메모리 개체가 명시 적으로 백업되지 않으며 이것이 문제 일 수 있습니다. 나는

https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateBuffer.html

같은 CL_MEM_USE_HOST_PTR, CL_MEM_COPY_HOST_PTR, 또는 CL_MEM_ALLOC_HOST_PTR로, 다음 호스트 포인터를 지정에서 플래그를 추가하는 것이 좋습니다 것입니다. CL_MEM_USE_HOST_PTR을 사용하면 버퍼가 호스트 메모리에있을 경우 버퍼가 호스트에 다시 할당되지 않고 단지 메모리 사용량 인 경우 문제를 해결하는 데 도움이됩니다.

+0

그래서'CL_MEM_COPY_HOST_PTR'로 당신의 접근 방식을 시도했는데 성능이 많이 느려지는 것 같았습니다. 먼저 입력 버퍼를 시도해 보았고 Interpolate 커널이 13ms 씩 뛰어 올랐습니다. 그럼 내가 출력 버퍼에 대한 동일한 시도, 프로그램이 추락했습니다. 보간 커널은 주어진 입력 배열에서 배열의 모든 'n 번째'위치에 요소를 추가하는 간단한 커널 일뿐입니다. – VedhaR

+0

@VedhaR'CL_MEM_COPY_HOST_PTR'을 권장하지는 않았지만'CL_MEM_USE_HOST_PTR'. – JavaProphet

+0

미안하지만 그게 'CL_MEM_USE_HOST_PTR'을 사용했다는 뜻입니다. 여기 상자에 잘못 입력했습니다. – VedhaR

관련 문제