Unterschiedliche Ergebnisse zwischen Debug und Release

Habe ich das problem, dass mein code gibt unterschiedliche Ergebnisse beim Vergleich von debug zu release. Ich habe überprüft, dass beide Modi mit /fp:precise, also das sollte nicht das problem sein. Das Hauptproblem habe ich mit diesem ist, dass die komplette image-Analyse (es ist ein Bild Verständnis project) ist vollständig deterministisch, es gibt absolut nichts zufällig.

Ein weiteres Problem mit diesem ist die Tatsache, dass meine Version tatsächlich immer liefert das gleiche Ergebnis (23.014 für die Bild), wenn der debug-gibt einen zufälligen Wert zwischen 22 und 23, die sollten einfach nicht sein. Ich habe bereits geprüft, ob es möglicherweise Faden verwandt, aber nur ein Teil des Algorithmus, die multi-Thread gibt der genau das gleiche Ergebnis für beide debug und release.

Was sonst noch hier passiert?

Update1: Der code, den ich jetzt verantwortlich für dieses Verhalten:

float PatternMatcher::GetSADFloatRel(float* sample, float* compared, int sampleX, int compX, int offX)
{
    if (sampleX != compX)
    {
        return 50000.0f;
    }
    float result = 0;

    float* pTemp1 = sample;
    float* pTemp2 = compared + offX;

    float w1 = 0.0f;
    float w2 = 0.0f;
    float w3 = 0.0f;

    for(int j = 0; j < sampleX; j ++)
    {
        w1 += pTemp1[j] * pTemp1[j];
        w2 += pTemp1[j] * pTemp2[j];
        w3 += pTemp2[j] * pTemp2[j];
    }               
    float a = w2 / w3;
    result = w3 * a * a - 2 * w2 * a + w1;
    return result / sampleX;
}

Update2:
Dies ist nicht reproduzierbar mit 32bit-code. Während der debug-und release-code wird immer der gleiche Wert für 32bit, es ist noch immer anders aus, die 64-bit version und die 64-bit-debug -, noch liefert einige absolut zufällige Werte.

Update3:
Okay, ich fand es, um sicher zu sein, verursacht durch OpenMP. Wenn ich es deaktivieren, funktioniert es einwandfrei. (sowohl Debug-als auch Release mit ein und demselben code, und beide haben OpenMP aktiviert).

Folgende code ist der code, gebe mir Mühe:

#pragma omp parallel for shared(last, bestHit, cVal, rad, veneOffset)
for(int r = 0; r < 53; ++r)
{
    for(int k = 0; k < 3; ++k)
    {
        for(int c = 0; c < 30; ++c)
        {
            for(int o = -1; o <= 1; ++o)
            {
                /*
                r: 2.0f - 15.0f, in 53 steps, representing the radius of blood vessel
                c: 0-29, in steps of 1, representing the absorption value (collagene)
                iO: 0-2, depending on current radius. Signifies a subpixel offset (-1/3, 0, 1/3)
                o: since we are not sure we hit the middle, move -1 to 1 pixels along the samples
                */

                int offset = r * 3 * 61 * 30 + k * 30 * 61 + c * 61 + o + (61 - (4*w+1))/2;

                if(offset < 0 || offset == fSamples.size())
                {
                    continue;
                }
                last = GetSADFloatRel(adapted, &fSamples.at(offset), 4*w+1, 4*w+1, 0);
                if(bestHit > last)
                {
                    bestHit = last;
                    rad = (r+8)*0.25f;
                    cVal = c * 2;
                    veneOffset =(-0.5f + (1.0f / 3.0f) * k + (1.0f / 3.0f) / 2.0f);
                    if(fabs(veneOffset) < 0.001)
                        veneOffset = 0.0f;
                }
                last = GetSADFloatRel(input, &fSamples.at(offset), w * 4 + 1, w * 4 + 1, 0);
                if(bestHit > last)
                {
                    bestHit = last;
                    rad = (r+8)*0.25f;
                    cVal = c * 2;
                    veneOffset = (-0.5f + (1.0f / 3.0f) * k + (1.0f / 3.0f) / 2.0f);
                    if(fabs(veneOffset) < 0.001)
                        veneOffset = 0.0f;
                }
            }
        }
    }
}

Hinweis: mit Release-Modus und OpenMP aktiviert ist, bekomme ich das gleiche Ergebnis wie mit der Deaktivierung von OpenMP. Debug-Modus und OpenMP aktiviert, bekommt ein anderes Ergebnis, OpenMP deaktiviert, erhält das gleiche Ergebnis wie bei Release.

  • Wir könnten mehr helfen, wenn wir sehen, einige code. Im Allgemeinen, meine Vermutung ist, dass Sie Locker syntax irgendwo, dass der normale compiler versteht richtig, aber der debugger nicht.
  • verwenden valgrind zu überprüfen, wenn Sie einige Speicher-Korruption, die möglicherweise dazu führen, dass nicht deterministisch Verhalten.
  • Interessant. Die üblichen Heisenbug situation ist, dass das debugging wird mehr zuverlässige Ergebnisse.
  • Riecht wie ein Undefiniertes Verhalten...
  • Release und debug sind nur verschiedene Sätze von Projekt-Optionen - Sie können ändern Sie die Optionen eins nach dem anderen, bis Sie finden, diejenigen, die in Ihrem Release-Ausgabe passen Sie Ihre Debug-Ausgabe. Aber wir haben nicht genug Informationen, um Ihnen zu sagen, was Los ist. Drucken Sie intermediate output, Teile und herrsche... 8 - )
  • Hinzufügen intermediate output wird wahrscheinlich Ergebnisse als es die Kräfte einer Ordnung der Operationen auf den compiler an. Legen Sie eine printf-Anweisung und kann das problem gehen Weg, nehmen Sie es wieder aus und das problem gibt.
  • Ich Neige dazu, zu widersprechen. Wenn er Einsätze printfs in der Mitte seiner Berechnung Schleifen dann ja etwas bekommen könnte nachbestellt werden. Aber wenn er ruft 10 numerische Routinen und überprüft die Eingabe - /Ausgabe-dann kann dieser Ansatz helfen, ihn zu finden Sie heraus, welche der Routinen geben unterschiedliche Ergebnisse bei debug und unter release. Wenn Sie stecken, können Sie versuchen, die Verengung, das problem...
  • Hmmm...siehe Felix von Leitner ' s umfangreiche Präsentation auf die aktuelle assembly produziert, die von verschiedenen c-Compiler (PDF-link!). Moderne Compiler können-und wird schwer zu manipulieren-code.
  • Sie haben viele unsynchronised Zugriffe auf shared-Variablen innerhalb der parallelen region last und bestHit werden die meisten offensichtlichen. Diese fordert, dass Probleme auftreten, wenn der code ausgeführt wird.

InformationsquelleAutor SinisterMJ | 2012-08-14
Schreibe einen Kommentar