为什么这段代码在 Debug 模式下运行速度比 Release 模式慢 100 倍以上?

GDN*_*DN9 1 c++ debugging performance visual-studio-2015

重新发帖原因:

本来我只得到一个回复​​,只是指出标题夸大了。因此,再试一次,也许这次会有更多的人看到这个问题,因为我真的不知道还能看哪里......我会确保删除原来的问题以避免重复,并保留这个新问题。我并不是想向论坛发送垃圾邮件。

请随意在编辑时删除上面的文本,我只是想解释为什么我要重新发布 - 但这并不是问题的一部分。

所以,最初的问题是:

我的程序中有一些函数在 Visual Studio Community,2015 中的调试模式下运行速度非常慢。它们是用于“索引”3D 模型顶点的函数。

通常情况下,我准备好调试模式会慢一点,可能慢 2 -3 倍。但...

发布模式下,程序将在大约2 - 3 秒内启动并索引模型。完美的。

然而,在调试模式下,我的程序需要7 分钟以上才能真正响应、开始渲染并接受输入。它在索引一个模型时卡住了七分钟多。在此期间程序完全冻结。

相同的模型在“发布”模式下加载和索引只需不到 3。调试过程中怎么可能花费如此长的时间?

调试和发布模式都是标准的开箱即用模式。我不记得更改过其中任何一个的任何设置。

以下是在调试模式下减慢程序速度的代码:

// 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++;
}
}
Run Code Online (Sandbox Code Playgroud)

然后是它使用的 2 个小“辅助”函数(isNear()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;
}
Run Code Online (Sandbox Code Playgroud)

上述功能的所有功劳都归于: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/

这可能是:

  1. Visual Studio 社区 2015 问题?
  2. VSC15 调试模式问题?
  3. 代码慢?(但它只是在调试时慢?!)

Ice*_*ire 5

有很多事情将/可能被优化:

  1. 使用索引迭代向量比[]使用迭代器慢;在调试中,这当然没有被优化,但在发布中可能会
  2. []此外,由于处于调试模式时的运行时检查和调试功能,访问向量 via 的速度很慢;当您执行以下操作时,可以很容易地看到这一点operator[]
  3. push_back并且size可能还有一些额外的检查,而不是使用发布模式时消失

所以,我的主要猜测是你用得[]太多了。当您使用真实迭代器更改迭代时,发布速度可能会更快。所以,而不是:

for (unsigned int i = 0; i < in_vertices.size(); i++) {
Run Code Online (Sandbox Code Playgroud)

使用:

for(auto& vertex : in_vertices)
Run Code Online (Sandbox Code Playgroud)

这间接使用了迭代器。你也可以明确地写:

   for(auto vertexIt = in_vertices.begin(); vertexIt != in_vertices.end(); ++vertexIt)
   {
      auto& vertex = *vertexIt;
Run Code Online (Sandbox Code Playgroud)

显然,这是较长的代码,看起来可读性较差,并且没有实际优势,除非您需要迭代器来实现某些其他功能。