2016-07-28 23 views
1

Ich habe erfolgreich einen Digital Down Converter mit OpenCL implementiert. Bei der Implementierung des Interpolationsteils kann ich nur einen maximalen Faktor von 146 einstellen. Jedes weitere führt dazu, dass das Programm abstürzt und ein Fehlercode von CL_INVALID_MEM_OBJECT -38 ausgelöst wird.OpenCL-Programm mit zu viel Speicher

Für diejenigen, die nicht wissen, Interpolation ist eine Methode zum Erstellen neuer Datenpunkte im Bereich der bekannten Datenpunkte. Der DDC (Digital Down Converter) wird verwendet, um die Abtastrate zu erhöhen oder zu verringern, während versucht wird, Datenpunkte mithilfe eines Rekonstruktionsfilters zu rekonstruieren.

Beachten Sie, dass die Datei, die ich verwende, eine 1,75 MB WAV-Datei als Eingabe ist. Es wird bei 44100 abgetastet und mein Ziel ist es, eine Abtastung bei 48000 zu machen (blaue Strahlenqualität). Dies ergibt einen Interpolations-/Dezimierungsfaktor von 160/147. Aber jeder Interpolationsfaktor über 146 stürzt die Treiber ab und das Programm und der Fehler für -38 werden wie oben gezeigt geworfen.

Ich denke, das Problem liegt wo ich die cl_mem Puffer erstellen. Ich habe ungefähr 7 und hier sind wie sie initialisiert und verwendet werden. Angenommen, P 3 und Q 2, während NUM_ITEMS 918.222 Proben:

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

ich die Speicher-Debugger in Visual Studio verwendet, um herauszufinden, dass das Programm 602Mb verwendet (für Interpolationsfaktor von 160, bevor es abstürzt es um 120 MB verwendet. für einen Faktor von 3, noch viel!) Wie kann ich das runter bringen? Benutze ich die Puffer falsch?

Darüber hinaus habe ich drei weitere Speicherzuordnungen im Host-Code. Das 'Array' hält einfach die Werte in der wav-Datei, während OutputData und OutputData2 Werte von der gefilterten Eingabe bzw. der dezimierten Eingabe speichern.

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

Das folgende ist ein Bild der Speichernutzung in Visual Studio, wenn P = 3 (Array von einer Größe von 3 erhöht wird).

enter image description here

ist hier einer der Schreibpuffer, wo ich die -38-Code.

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

Hier ist der Tiefpass kernel:

__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 Fehler tritt auf, weil die Puffergröße I zuteilen 512 MB Arbeitsspeicher verfügt über verwendet werden. Das ist die maximale Größe eines Puffers, den ich haben kann. Um dieses Problem zu beheben, muss ich eine Art Speicherverwaltungssystem in meinen Code implementieren. Vielleicht mit einem 8 MB Puffer auf einmal.

+0

Können Sie uns zeigen, wo Sie in diese Puffer schreiben und wo Sie Ihren Kernel aufrufen? (und Cleanup-Code könnte auch eine gute Idee sein) 'CL_INVALID_MEM_OBJECT' Ich denke nicht, dass' clCreateBuffer' geworfen wird. – JavaProphet

+0

@JavaProphet Ich habe sowohl den WriteBuffer als auch den Kernel hinzugefügt. Es wirft auch den gleichen Fehler für den dezimierten Kernel. Ich werde versuchen, die Protokollmeldung hinzuzufügen, die ausgegeben wird, wenn dieser Fehler ebenfalls auftritt. – VedhaR

Antwort

0

Ihre Speicherobjekte werden nicht explizit von irgendetwas unterstützt, und das könnte Ihr Problem sein. Ich würde empfehlen, eine Fahne von

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

wie CL_MEM_USE_HOST_PTR Zugabe, CL_MEM_COPY_HOST_PTR oder CL_MEM_ALLOC_HOST_PTR, dann einen Host-Zeiger angibt. Wenn Sie CL_MEM_USE_HOST_PTR verwenden, wird der Puffer nicht erneut auf dem Host zugewiesen, wenn er im Arbeitsspeicher des Hosts vorhanden ist, was möglicherweise zu Ihrem Problem beiträgt, wenn es sich nur um die Speichernutzung handelt.

+0

Also habe ich Ihren Ansatz mit 'CL_MEM_COPY_HOST_PTR' versucht und es schien, dass die Leistung viel langsamer wird. Ich habe es zuerst für den Eingabepuffer ausprobiert und festgestellt, dass der Interpolate-Kernel um 13ms gesprungen ist. Wenn ich das gleiche für den Ausgabepuffer versuchte, stürzte das Programm ab. Der interpolierte Kernel ist nur ein einfacher Kernel, der ein Element an jeder "n-ten" Position in dem Array von einem gegebenen Eingabe-Array hinzufügt. – VedhaR

+0

@VedhaR Ich habe 'CL_MEM_COPY_HOST_PTR', aber' CL_MEM_USE_HOST_PTR' nicht empfohlen. – JavaProphet

+0

Entschuldigung, das meine ich, ich habe 'CL_MEM_USE_HOST_PTR' verwendet, ich habe es einfach falsch in die Box kopiert. – VedhaR