/ / Prečo je tento kód v režime ladenia spustený stokrát pomalšie ako vydanie? - c ++, výkon, ladenie, vizuálne štúdio-2015

Prečo tento kód beží v ladiacom režime viac ako stokrát pomalšie ako Uvoľniť? - c ++, performance, ladenie, vizuálne štúdio-2015

Dôvod opätovného uverejnenia príspevku:

Pôvodne som dostal iba jednu odpoveď, iba túpoukázal na to, že nadpis bol prehnaný. Preto to skúsim znova, možno túto otázku uvidí tentoraz viac ľudí, pretože naozaj neviem, kde inde hľadať ... Pôvodnú otázku odstránim, aby sa zabránilo duplicite, a namiesto toho si ponechám túto novú. Nesnažím sa spamovať na fóre.

Po úpravách môžete vyššie uvedený text odstrániť. Len som chcel vysvetliť, prečo znova uverejňujem príspevky, ale nie je to skutočne súčasť otázky.

Pôvodná otázka teda znela:

Vo svojom programe mám niekoľko funkcií, ktoré v režime ladenia bežia extrémne pomaly, v komunite Visual Studio, 2015. Sú to funkcie na „indexovanie“ vertov 3D modelov.

Normálne som pripravený na to, že režim ladenia bude trochu pomalší, možno 2 - 3-krát pomalší. Ale ...

v uvoľnenie režime sa program spustí a indexuje modely v približne 2 - 3 sekundy. Dokonalá.

v ladiť režim však prevezme 7 MINÚT aby môj program skutočne odpovedal, spustil vykresľovanie a prijal vstup. Je to zaseknuté indexovanie jedného modelu na viac ako sedem minút. Počas tejto doby je program úplne zmrazený.

Rovnaký model sa načíta a indexuje v režime „Release“ za menej ako 3 sekundy. Ako je možné, že to v Debugu trvá tak neuveriteľne dlho?

Režimy Debug & Release sú štandardom po vybalení z krabice. Nepamätám si, že by som zmenil ktorékoľvek z nastavení niektorého z nich.

Tu je kód, ktorý spomaľuje program v režime ladenia:

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

A potom dve malé „pomocné“ funkcie, ktoré používa (isNear() a 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;
}

Všetky zásluhy za vyššie uvedené funkcie patria: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/

Môže to byť:

  1. Problém s komunitou Visual Studio 2015?
  2. Problém s režimom ladenia VSC15?
  3. Pomalý kód? (Ale v Debugu je to len pomalé ?!)

odpovede:

3 pre odpoveď č. 1

Existuje niekoľko vecí, ktoré budú / môžu byť optimalizované:

  1. iterácia vektora s indexmi [] je pomalší ako použitie iterátorov; pri ladení to určite nie je optimalizované, ale pri vydaní by to mohlo byť
  2. navyše prístup k vektoru cez [] je pomalý kvôli kontrolám za behu a funkciám ladenia, keď je v režime ladenia; to je pomerne ľahko viditeľné, keď idete na implementáciu operator[]
  3. push_back a size môže mať aj ďalšie kontroly, ako odpadnúť pri použití režimu uvoľnenia

Takže môj hlavný odhad by bol, že používate [] príliš veľa. Vydanie môže byť ešte rýchlejšie, keď zmeníte iteráciu pomocou skutočných iterátorov. Takže namiesto:

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

použitia:

for(auto& vertex : in_vertices)

Toto nepriamo používa iterátory. Môžete tiež výslovne napísať:

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

Je zrejmé, že ide o dlhší kód, ktorý sa zdá byť menej čitateľný a nemá žiadnu praktickú výhodu, pokiaľ nepotrebujete iterátor pre niektoré ďalšie funkcie.