/ / Pourquoi ce code s'exécute-t-il 100 fois plus lentement en mode débogage qu'en version? - c ++, performance, débogage, visual-studio-2015

Pourquoi ce code fonctionne-t-il plus de 100 fois plus lentement en mode débogage qu'en version? - c ++, performance, débogage, visual-studio-2015

Raison de la nouvelle publication:

À l'origine, je n'ai reçu qu'une seule réponse,a souligné que le titre était exagéré. Par conséquent, en essayant à nouveau, peut-être que plus de gens verront cette question cette fois car je ne sais vraiment pas où chercher ... Je m'assurerai de supprimer la question d'origine pour éviter les doublons et de conserver cette nouvelle à la place. Je n'essaie pas de spammer le forum.

N'hésitez pas à supprimer le texte ci-dessus lors de la modification, je voulais juste expliquer pourquoi je "re-poste" - mais ce n'est pas vraiment une partie de la question.

Donc, la question initiale était:

J'ai quelques fonctions dans mon programme qui fonctionnent extrêmement lentement en mode débogage, dans Visual Studio Community, 2015. Ce sont des fonctions pour "indexer" les verts des modèles 3D.

Normalement, je suis prêt à ce que le mode débogage soit un peu plus lent, peut-être 2 à 3 fois plus lent. Mais ...

Dans Libération mode, le programme démarre et indexe les modèles dans environ 2 à 3 secondes. Parfait.

Dans Déboguer cependant, il prend le relais 7 MINUTES pour que mon programme réponde réellement, pour commencer le rendu et prendre des entrées. Il est bloqué en indexant un modèle pendant plus de sept minutes. Pendant ce temps, le programme est complètement gelé.

Le même modèle se charge et indexe en mode "Release" en moins de 3 secondes. Comment est-il possible que cela prenne autant de temps dans Debug?

Les deux modes Debug & Release sont les modes standard prêts à l'emploi. Je ne me souviens pas avoir changé l'un des paramètres de l'un ou l'autre.

Voici le code qui ralentit le programme en mode débogage:

// Main Indexer Function
void indexVBO_TBN(
std::vector<glm::vec3> &in_vertices,
std::vector<glm::vec2> &in_uvs,
std::vector<glm::vec3> &in_normals,
std::vector<glm::vec3> &in_tangents,
std::vector<glm::vec3> &in_bitangents,

std::vector<unsigned short> & out_indices,
std::vector<glm::vec3> &out_vertices,
std::vector<glm::vec2> &out_uvs,
std::vector<glm::vec3> &out_normals,
std::vector<glm::vec3> &out_tangents,
std::vector<glm::vec3> &out_bitangents){

int count = 0;

// For each input vertex
for (unsigned int i = 0; i < in_vertices.size(); i++) {

// Try to find a similar vertex in out_vertices, out_uvs, out_normals, out_tangents & out_bitangents
unsigned int index;
bool found = getSimilarVertexIndex(in_vertices[i], in_uvs[i], in_normals[i], out_vertices, out_uvs, out_normals, index);

if (found) {
// A similar vertex is already in the VBO, use it instead !
out_indices.push_back(unsigned short(index));

// Average the tangents and the bitangents
out_tangents[index] += in_tangents[i];
out_bitangents[index] += in_bitangents[i];
} else {
// If not, it needs to be added in the output data.
out_vertices.push_back(in_vertices[i]);
out_uvs.push_back(in_uvs[i]);
out_normals.push_back(in_normals[i]);
out_tangents.push_back(in_tangents[i]);
out_bitangents.push_back(in_bitangents[i]);
out_indices.push_back((unsigned short)out_vertices.size() - 1);
}
count++;
}
}

Et puis les 2 petites fonctions "helper" qu'il utilise (isNear() et getSimilarVertexIndex()):

// Returns true if v1 can be considered equal to v2
bool is_near(float v1, float v2){
return fabs( v1-v2 ) < 0.01f;
}


bool getSimilarVertexIndex( glm::vec3 &in_vertex, glm::vec2 &in_uv, glm::vec3 &in_normal,
std::vector<glm::vec3> &out_vertices, std::vector<glm::vec2> &out_uvs, std::vector<glm::vec3> &out_normals,
unsigned int &result){
// Lame linear search
for (unsigned int i = 0; i < out_vertices.size(); i++) {

if (is_near(in_vertex.x, out_vertices[i].x) &&
is_near(in_vertex.y, out_vertices[i].y) &&
is_near(in_vertex.z, out_vertices[i].z) &&
is_near(in_uv.x, out_uvs[i].x) &&
is_near(in_uv.y, out_uvs[i].y) &&
is_near(in_normal.x, out_normals[i].x) &&
is_near(in_normal.y, out_normals[i].y) &&
is_near(in_normal.z, out_normals[i].z)
) {
result = i;
return true;
}
}
return false;
}

Tout crédit pour les fonctions ci-dessus va à: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/

Serait-ce un:

  1. Problème avec Visual Studio Community 2015?
  2. Problème de mode de débogage VSC15?
  3. Code lent? (Mais c'est seulement lent dans Debug?!)

Réponses:

3 pour la réponse № 1

Il y a plusieurs choses qui seront / pourraient être optimisées:

  1. itération d'un vecteur avec des indices [] est plus lent que l'utilisation d'itérateurs; dans le débogage, ce n'est certainement pas optimisé, mais dans la version, il pourrait
  2. en outre, l'accès à un vecteur via [] est lent en raison des vérifications d'exécution et des fonctionnalités de débogage en mode de débogage; cela peut être assez facilement vu lorsque vous passez à la mise en œuvre de operator[]
  3. push_back et size pourrait également avoir des vérifications supplémentaires que tomber lors de l'utilisation du mode de libération

Donc, ma principale supposition serait que vous utilisez [] trop. Il peut être encore plus rapide dans la version lorsque vous modifiez l'itération en utilisant de vrais itérateurs. Donc, au lieu de:

for (unsigned int i = 0; i < in_vertices.size(); i++) {

utilisation:

for(auto& vertex : in_vertices)

Cela utilise indirectement des itérateurs. Vous pouvez également écrire explicitement:

   for(auto vertexIt = in_vertices.begin(); vertexIt != in_vertices.end(); ++vertexIt)
{
auto& vertex = *vertexIt;

Évidemment, il s'agit d'un code plus long qui semble moins lisible et n'a aucun avantage pratique, sauf si vous avez besoin de l'itérateur pour d'autres fonctions.