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/
这可能是:
有很多事情将/可能被优化:
[]
使用迭代器慢;在调试中,这当然没有被优化,但在发布中可能会[]
此外,由于处于调试模式时的运行时检查和调试功能,访问向量 via 的速度很慢;当您执行以下操作时,可以很容易地看到这一点operator[]
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)
显然,这是较长的代码,看起来可读性较差,并且没有实际优势,除非您需要迭代器来实现某些其他功能。