2017-02-21 4 views
0

Ich habe ein Problem mit dem lokalen Speicher, konkret mit dem Wert zu sparen. Dies sind alle Kernel in der Datei, die zum Programm geladen werden.OpenCL lokale Arbeit lokaler Speicher

__kernel void initData(int bitSample, int transmitorCount ,int bufferLen, __global short *sequence) 
{ 

    __local int constData[2]; 
    __local short mask[(15 * 1023)]; 

    constData[0] = bitSample; 
    constData[1] = bufferLen; 

    for (int i = 0; i < transmitorCount * 1023; i++) { 
     mask[i] = sequence[i]; 
    } 

    printf("startPlace: %u \t Resutl: %i = %i\n", transmitorCount, constData[0], constData[1]); 
    barrier(CLK_LOCAL_MEM_FENCE); 
} 

__kernel void correlation(__global short *inBuffer, __global int *outBuffer, __local int *constData) 
{ 

    uint startPlace = get_global_id(0); 
    uint sequence = get_global_id(1); 

    outBuffer[0] = inBuffer[0]; 

    printf("startPlace: %i Sequence: %i\t Resutl: %i = %i\n", startPlace, sequence, constData[0], constData[1]); 
} 

Programm funktioniert und lokaler Speicher wird gespeichert. Initialisierungsaufruf ist:

Aber wenn ich Korrelationskernel starte, gespeicherte Werte in lokalen nur beim ersten Start. Zweiter und nächster Start sind falsche Daten. Ich versuche, den lokalen Speicher vor jedem Start zu initialisieren, aber es funktioniert nicht. Erstellen Befehl Warteschlange ist:

while(true){ 
    ret = clSetKernelArg(gpuControlData->corelationKernel, 0, sizeof(cl_mem), (void *) &inBuffer); 
    ret = clSetKernelArg(gpuControlData->corelationKernel, 1, sizeof(cl_mem), (void *)&outBuffer); 
    ret = clSetKernelArg(gpuControlData->corelationKernel, 2, sizeof(cl_int) * 2, NULL); 

    size_t globaId[3] = { 3, 2, 0 }; 
    ret = clEnqueueNDRangeKernel(gpuControlData->maskCorrelQueue, gpuControlData->corelationKernel, 2, NULL, globaId, NULL, 0, NULL, NULL); 
} 

Das Ergebnis eines Durchlaufs ist:

startPlace: 2 Resutl: 100 = 150000 
startPlace: 0 Sequence: 0  Resutl: 100 = 150000 
startPlace: 1 Sequence: 0  Resutl: 100 = 150000 
startPlace: 2 Sequence: 0  Resutl: 100 = 150000 
startPlace: 0 Sequence: 1  Resutl: 100 = 150000 
startPlace: 1 Sequence: 1  Resutl: 100 = 150000 
startPlace: 2 Sequence: 1  Resutl: 100 = 150000 
oneIteration 
startPlace: 0 Sequence: 0  Resutl: 1056562655 = 1058300571 
startPlace: 1 Sequence: 0  Resutl: 1056562655 = 1058300571 
startPlace: 2 Sequence: 0  Resutl: 1056562655 = 1058300571 
startPlace: 0 Sequence: 1  Resutl: 1056562655 = 1058300571 
startPlace: 1 Sequence: 1  Resutl: 1056562655 = 1058300571 
startPlace: 2 Sequence: 1  Resutl: 1056562655 = 1058300571 

Also ich brauche etwas Hilfe oder ein Beispiel, wie man mit gleichen lokalen Daten-Kernel in Schleife laufen?

Danke für Hilfe.

+0

Wenn mein Speicher dient, werden Daten im lokalen Speicher zwischen den Wellenfronten nicht beibehalten. Und ich denke, ich weiß nicht, was du machen wolltest. – BlueWanderer

+0

Ich möchte Daten vergleichen. Eine Daten ist definiert und statische und zweite Daten sind Änderungen. Daher möchte ich konstante Daten im lokalen Speicher für einen schnelleren Zugriff speichern. Ich muss inBuffer für jede Iteration chance. –

+0

@StepanRydlo Alle Threads in einer Arbeitsgruppe können Daten vom globalen Speicher zum lokalen Speicher sammeln, und sie tun dies gleichzeitig. Sie können also einen einzelnen Kernel haben, der sowohl Initialisierung als auch Korrelation durchführt. Sie müssen vor dem Starten der Korrelation mit einem Barrierebefehl synchronisiert werden. –

Antwort

2

Lokaler Speicher ist im Wesentlichen "Scratch" Speicher und behält seinen Inhalt nach dem Ende des Kernels nicht. Sie initialisieren es normalerweise im Kernel, um als manueller Cache zu dienen. Sie können nicht tun, was Sie mit dem lokalen Speicher versuchen.

Sie können const Speicher verwenden, um den Speicherzugriff zu beschleunigen. Der Const-Speicher verwendet wahrscheinlich den tatsächlichen Cache des Geräts und wird eine mit der lokalen Geschwindigkeit vergleichbare Geschwindigkeit haben. Das einzige Problem ist, dass es keine Möglichkeit gibt, zu garantieren (oder zu wissen), wenn der Speicher zwischengespeichert wird - es könnte am Ende nur global sein. Sie müssen experimentieren.

+0

Ich möchte fragen, wie man einen konstanten globalen Puffer erstellt. Ich finde kein Beispiel. Ich erstelle Puffer CL_MEM_READ_ONLY und im Kernel benutze ich das Argument __constant short * mask. Aber es gibt keinen Unterschied zu schnell. Sp wie erstelle ich einen konstanten Puffer? –

+0

Woher weißt du, dass konstantes Gedächtnis der Flaschenhals ist?Hast du alles überprüft? –

+0

Solange der konstante Speicher kleiner als 16 KB ist, sollte in jedem CL-Desktop-Gerät in Ordnung sein. – DarkZeros