为什么这段代码在 Debug 模式下运行比 Release 慢 100 多倍? [英] Why is this code running over 100 times slower in Debug mode than Release?

查看:50
本文介绍了为什么这段代码在 Debug 模式下运行比 Release 慢 100 多倍?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

重新发布的原因:

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

Originally I got only one reply, that only pointed out that the title was exaggerated. Hence trying again, maybe more people will see this question this time as I really do not know where else to look... I will make sure to delete the original question to avoid duplication, and keep this new one instead. I'm not trying to spam the forum.

编辑时可以随意删除上面的文字,我只是想解释一下我重新发布的原因 - 但这并不是问题的一部分.

Feel free to remove the text above upon editing, I just wanted to explain why I'm re-posting - but it's not really a part of the question.

所以,最初的问题是:

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

I have a few functions in my program that run extremely slow in Debug mode, in Visual Studio Community, 2015. They are functions to "index" the verts of 3D models.

通常,我准备让调试模式慢一点,可能慢 2 -3 倍.但是...

Normally, I'm prepared for Debug mode to be a little slower, maybe 2 -3 times slower. But...

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

In Release mode, the program starts and indexes the models in about 2 - 3 seconds. Perfect.

然而,在调试模式下,我的程序需要7分钟来实际响应,开始渲染并接受输入.它在索引一个模型时卡住了超过 7 分钟.在此期间,程序完全冻结.

In Debug mode however, it takes over 7 MINUTES for my program to actually respond, to start rendering and take input. It is stuck indexing one model for over seven minutes. During this time the program is completely froze.

同一模型在发布"模式下的加载和索引不到 3 .在 Debug 中花费如此令人难以置信的时间怎么可能?

The same model loads and indexes in "Release" mode in less than 3 seconds. How is it possible that it takes so unbelievably long in Debug?

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

Both Debug & Release modes are the standard out of the box modes. I don't recall changing any of the settings in either of them.

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

Here's the code that's slowing the program down in Debug mode:

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

然后是它使用的 2 个小辅助"函数(isNear()getSimilarVertexIndex()):

And then the 2 little "helper" functions it uses (isNear() and 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;
}

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

All credit for the functions above goes to: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/

这可能是:

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

推荐答案

有很多事情需要/可能会被优化:

There are multiple things that will/might be optimized:

  1. 用索引[] 迭代一个向量比使用迭代器慢;在调试中,这当然没有优化,但在发布时可能
  2. 此外,由于处于调试模式时的运行时检查和调试功能,通过 [] 访问向量很慢;当您转到 operator[]
  3. 的实现时,可以很容易地看到这一点
  4. push_backsize 也可能有一些额外的检查,而不是在使用发布模式时失效
  1. iterating a vector with indices [] is slower than using iterators; in debug, this certainly is not optimized away but in release it might
  2. additionally, accessing a vector via [] is slow because of runtime checks and debugging features when being in debug mode; this can be fairly easily seen when you go to the implementation of operator[]
  3. push_back and size might also have some additional checks than fall away when using release mode

所以,我的主要猜测是您使用 [] 太多了.当您通过使用真正的迭代器来更改迭代时,它的发布速度可能会更快.所以,而不是:

So, my main guess would be that you use [] too much. It might be even faster in release when you change the iteration by means of using real iterators. So, instead of:

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

使用:

for(auto& vertex : in_vertices)

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

This indirectly uses iterators. You could also explicitly write:

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

显然,这是一段较长的代码,看起来可读性较差并且没有实际优势,除非您需要其他一些函数的迭代器.

Obviously, this is longer code that seems less readable and has no practical advantage, unless you need the iterator for some other functions.

这篇关于为什么这段代码在 Debug 模式下运行比 Release 慢 100 多倍?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆