Des résultats différents entre Debug et Release

J'ai le problème que mon code renvoie des résultats différents lors de la comparaison de débogage pour publication. J'ai vérifié que les deux modes d'utilisation /fp:précis, ce qui ne devrait pas être le problème. Le principal problème que j'ai avec c'est que l'image complète de l'analyse (c'est une image de la compréhension du projet) est complètement déterministe, il n'y a absolument rien au hasard en elle.

Un autre problème, c'est le fait que ma version de construire en réalité toujours renvoie le même résultat (23.014 pour l'image), tout en debug certains retours valeur aléatoire entre le 22 et le 23, le tout ne devrait pas être. J'ai déjà vérifié si elle peut être fil, mais la seule partie de l'algorithme qui est multi-thread renvoie précisément le même résultat pour le debug et release.

Quoi d'autre peut-être ce qui se passe ici?

Update1: Le code que j'ai maintenant trouvé responsables de ce comportement:

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:
Ce n'est pas reproductible avec 32 bits de code. Tout en debug et release code entraînera toujours la même valeur pour les 32 bits, c'est encore différent de la version 64bit version, et la version 64bit de débogage encore certains retours complètement aléatoire des valeurs.

Update3:
Bon, je l'ai trouvé certainement être causée par OpenMP. Quand je le désactiver, il fonctionne très bien. (Debug et Release utiliser le même code, et les deux ont OpenMP activé).

Voici le code à me donner de la difficulté à:

#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;
}
}
}
}
}

Remarque: avec la Version mode et OpenMP activé-je obtenir le même résultat qu'avec la désactivation d'OpenMP. Le mode de débogage et OpenMP activé obtient un résultat différent, OpenMP désactivé obtient le même résultat qu'avec la Libération.

  • Nous pourrions être en mesure d'aider plus si nous voyons un peu de code. En général, je suppose que vous vous êtes en vrac à l'aide de la syntaxe quelque part que le compilateur comprend correctement, mais que le débogueur n'est pas.
  • utiliser valgrind pour vérifier si vous avez certains de corruption de la mémoire qui peut entraîner la non déterministe du comportement.
  • Intéressant. L'habitude Heisenbug situation est que le débogage obtient des résultats plus fiables.
  • Sent comme un comportement indéterminé...
  • Release et debug sont juste différents ensembles des options du projet - vous pouvez modifier les options une par une jusqu'à trouver ceux qui font de votre Libération de sortie correspondent à votre sortie de Débogage. Mais nous n'avons pas assez d'info pour vous dire ce qu'il se passe. Imprimer la production intermédiaire, diviser pour régner... 8 - )
  • L'ajout de la production intermédiaire sera susceptible de changer les résultats, car il oblige à une commande d'opérations sur le compilateur. Insérer une instruction printf et le problème peut disparaître; le reprendre et le problème revient.
  • J'ai tendance à être en désaccord. Si il insère des printfs dans le milieu de son calcul des boucles alors oui, quelque chose pourrait être réorganisées. Mais si il a des appels de 10 numérique des routines et des vérifications de l'entrée/sortie ensuite, cette approche peut aider à trouver les routines de donner des résultats différents en vertu de debug et en vertu de la libération. Si vous êtes coincé, vous pouvez précisez le problème...
  • Hmmm...voir Felix von Leitner est présentation complet sur le montage lui-même produit par les différents compilateurs c (lien PDF!). Les compilateurs modernes peuvent et vont fortement manipuler votre code.
  • Vous avez beaucoup de non synchronisés accès aux variables partagées à l'intérieur de la région parallèle, last et bestHit être les plus évidentes. Cette appels pour des problèmes lors de l'exécution du code.

InformationsquelleAutor SinisterMJ | 2012-08-14