Warum synchronisiert Barrier Shared Memory, MemoryBarrier nicht?

Der folgende GLSL-Compute-Shader kopiert einfachinImage zuoutImage. Es wird aus einem komplexeren Nachbearbeitungsdurchlauf abgeleitet.

In den ersten Zeilen vonmain()lädt ein einzelner Thread 64 Pixel Daten in das gemeinsam genutzte Array. Nach der Synchronisation schreibt dann jeder der 64 Threads ein Pixel in das Ausgabebild.

Je nachdem, wie ich synchronisiere, erhalte ich unterschiedliche Ergebnisse. Ich dachte ursprünglichmemoryBarrierShared() wäre der richtige Aufruf, führt aber zu folgendem Ergebnis:

Das ist das gleiche Ergebnis, als hätte man keine Synchronisation oder VerwendungmemoryBarrier() stattdessen.

Wenn ich benutzebarrier()Ich erhalte folgendes (gewünschtes) Ergebnis:

Das Striping ist 32 Pixel breit, und wenn ich die Arbeitsgruppengröße auf höchstens 32 ändere, erhalte ich korrekte Ergebnisse.

Was ist denn hier los? Verstehe ich den Zweck vonmemoryBarrierShared()? Warum sollbarrier() Arbeit?

#version 430

#define SIZE 64

layout (local_size_x = SIZE, local_size_y = 1, local_size_z = 1) in;

layout(rgba32f) uniform readonly  image2D inImage;
uniform writeonly image2D outImage;

shared vec4 shared_data[SIZE];

void main() {
    ivec2 base = ivec2(gl_WorkGroupID.xy * gl_WorkGroupSize.xy);
    ivec2 my_index = base + ivec2(gl_LocalInvocationID.x,0);

    if (gl_LocalInvocationID.x == 0) {
        for (int i = 0; i < SIZE; i++) {
            shared_data[i] = imageLoad(inImage, base + ivec2(i,0));
        }
    }

    // with no synchronization:   stripes
    // memoryBarrier();        // stripes
    // memoryBarrierShared();  // stripes
    // barrier();              // works

    imageStore(outImage, my_index, shared_data[gl_LocalInvocationID.x]);
}

Antworten auf die Frage(1)

Ihre Antwort auf die Frage