/ / Por que este código é executado 100 vezes mais lento no modo de depuração do que no Release? - c ++, desempenho, depuração, visual-studio-2015

Por que esse código está sendo executado 100 vezes mais lento no modo Debug que o Release? - c ++, desempenho, depuração, visual-studio-2015

Motivo para nova postagem:

Originalmente, recebi apenas uma resposta, que apenasapontou que o título era exagerado. Por isso, tente novamente, talvez mais pessoas vejam esta pergunta desta vez, pois eu realmente não sei onde mais procurar ... Certificarei de excluir a pergunta original para evitar duplicações e manter esta nova. Não estou tentando fazer spam no fórum.

Sinta-se à vontade para remover o texto acima ao editar, eu só queria explicar por que estou postando novamente - mas isso não faz parte da pergunta.

Então, a pergunta original era:

Tenho algumas funções em meu programa que são executadas de forma extremamente lenta no modo Debug, no Visual Studio Community, 2015. São funções para "indexar" as versões de modelos 3D.

Normalmente, estou preparado para que o modo de depuração seja um pouco mais lento, talvez 2 a 3 vezes mais lento. Mas ...

Dentro Lançamento modo, o programa inicia e indexa os modelos em cerca de 2 a 3 segundos. Perfeito.

Dentro Depurar modo no entanto, ele assume 7 MINUTOS para que meu programa realmente responda, comece a renderizar e receba a entrada. Ele está parado indexando um modelo por mais de sete minutos. Durante este tempo, o programa está completamente congelado.

O mesmo modelo carrega e indexa no modo "Release" em menos de 3 segundos. Como é possível que demore tanto em Debug?

Ambos os modos Debug e Release são os modos padrão prontos para uso. Não me lembro de ter alterado nenhuma das configurações em nenhum deles.

Este é o código que está retardando o programa no modo de depuração:

// 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++;
}
}

E então as 2 pequenas funções "auxiliares" que ele usa (isNear() e 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;
}

Todos os créditos pelas funções acima vão para: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/

Pode ser um:

  1. Problema do Visual Studio Community 2015?
  2. Problema no modo de depuração do VSC15?
  3. Código lento? (Mas só é lento no Debug ?!)

Respostas:

3 para resposta № 1

Existem várias coisas que serão / podem ser otimizadas:

  1. iterando um vetor com índices [] é mais lento do que usar iteradores; na depuração, isso certamente não é otimizado, mas na versão pode
  2. além disso, acessando um vetor via [] é lento por causa das verificações de tempo de execução e recursos de depuração quando está no modo de depuração; isso pode ser facilmente visto quando você vai para a implementação de operator[]
  3. push_back e size também pode ter algumas verificações adicionais do que cair ao usar o modo de liberação

Então, meu principal palpite é que você usa [] demais. Pode ser ainda mais rápido no lançamento quando você altera a iteração por meio do uso de iteradores reais. Então, em vez de:

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

usar:

for(auto& vertex : in_vertices)

Isso usa indiretamente iteradores. Você também pode escrever explicitamente:

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

Obviamente, esse é um código mais longo que parece menos legível e não tem nenhuma vantagem prática, a menos que você precise do iterador para algumas outras funções.