【问题标题】:C++ How to make long computations workC ++如何使长时间计算工作
【发布时间】:2014-12-20 08:19:13
【问题描述】:

我正在制作一个体素引擎的原型,但还没有像八叉树这样的优化,所以我正在计算每个体素以进行剔除,这需要很长时间。 当我有一个 16*16*16 的体素贴图来计算时,计算和渲染所需的时间不到 0.1 秒。

但是当我有像 100*32*100 这样更大的地图时,它永远不会结束计算(等了 10 分钟仍然没有渲染),我有一个白屏,程序就像卡在一个无限循环中,但它不应该是无限。

计算有时间限制吗?

编辑: 这是剔除的循环:

for (auto it = Chunk.begin(); it != Chunk.end(); ++it)
{
    if ((*it).w != 0)
    {
        Vector3f position = Vector3f((*it).x, (*it).y, (*it).z);
        Vector3f top(position.x, position.y + 1, position.z);
        Vector3f down(position.x, position.y - 1, position.z);
        Vector3f front(position.x, position.y, position.z - 1);
        Vector3f back(position.x, position.y, position.z + 1);
        Vector3f left(position.x + 1, position.y, position.z);
        Vector3f right(position.x - 1, position.y, position.z);

        auto findTop = std::find_if(Chunk.begin(), Chunk.end(), [=](Vector4f vec) { if (top == Vector3f(vec.x, vec.y, vec.z)) { return true; } else { return false; } });
        auto findDown = std::find_if(Chunk.begin(), Chunk.end(), [=](Vector4f vec) { if (down == Vector3f(vec.x, vec.y, vec.z)) { return true; } else { return false; } });
        auto findFront = std::find_if(Chunk.begin(), Chunk.end(), [=](Vector4f vec) { if (front == Vector3f(vec.x, vec.y, vec.z)) { return true; } else { return false; } });
        auto findBack = std::find_if(Chunk.begin(), Chunk.end(), [=](Vector4f vec) { if (back == Vector3f(vec.x, vec.y, vec.z)) { return true; } else { return false; } });
        auto findLeft = std::find_if(Chunk.begin(), Chunk.end(), [=](Vector4f vec) { if (left == Vector3f(vec.x, vec.y, vec.z)) { return true; } else { return false; } });
        auto findRight = std::find_if(Chunk.begin(), Chunk.end(), [=](Vector4f vec) { if (right == Vector3f(vec.x, vec.y, vec.z)) { return true; } else { return false; } });

        bool isTopOpaque, isDownOpaque, isFrontOpaque, isBackOpaque, isLeftOpaque, isRightOpaque;

        if (findTop == Chunk.end())
            isTopOpaque = false;
        else
            isTopOpaque = findTop->w;

        if (findDown == Chunk.end())
            isDownOpaque = false;
        else
            isDownOpaque = findDown->w;

        if (findFront == Chunk.end())
            isFrontOpaque = false;
        else
            isFrontOpaque = findFront->w;

        if (findBack == Chunk.end())
            isBackOpaque = false;
        else
            isBackOpaque = findBack->w;

        if (findLeft == Chunk.end())
            isLeftOpaque = false;
        else
            isLeftOpaque = findLeft->w;

        if (findRight == Chunk.end())
            isRightOpaque = false;
        else
            isRightOpaque = findRight->w;

        if (!(isTopOpaque && isDownOpaque && isFrontOpaque && isBackOpaque && isLeftOpaque && isRightOpaque))
        {
            glm::mat4 modelM = glm::translate(glm::mat4(1.0f), glm::vec3(2.0 * position.x, position.y * 2.0, 2.0 * position.z));
            size++;
            modelMatrices.push_back(modelM);
        }
    }   
}

“块”是 4d 向量的 std::vector,(x,y,z) 是位置,(w) 表示它是否不透明 (1) 或不透明 (0)。我正在使用 VS2013 IDE。

【问题讨论】:

  • 为你的算法计算大哦。插入数字,看看它有多糟糕:)
  • 没有代码,甚至没有提及您的目标环境,不可能说太多有用的东西。
  • 您的算法可能效率低下。你可以阅读数学书籍来提高它。你可以并行化它。您应该要求编译器对其进行优化。展示更多源代码,展示你的编译命令和你的环境(编译器、操作系统)!编辑您的问题以改进它!
  • 听起来您将体素存储为(无序?)坐标列表,这意味着任何空间参考都需要在列表中进行搜索。这是一种存储空间数据的低效方式。您还将体素称为 16x16x16。这是否意味着这些位置实际上是矩形且间隔均匀的?然后只需存储一个 16*16*16 的 bool 向量来表示您的体素以及尺寸。查找 w 现在只是一个索引操作,前面是 3D 限制检查。
  • “它永远不会结束”:你等到时间结束了吗?

标签: c++ optimization


【解决方案1】:

这 6 个 find_if 调用对循环的每次迭代进行线性搜索并比较向量。该算法是 N^2 的顺序,对于较大的情况会很慢。

如果您的向量包含 1000 个元素,则 find_if 调用可能会在最坏的情况下比较 6,000,000 个元素。在 2000 个元素时,它会跳到 24,000,000 次比较。

如果您运行的是 VS 2013 Professional 或更高版本,只需针对较小的情况分析代码并查看算法将时间花在哪里。解决性能问题的第 1 步是收集实际测量结果,以了解需要改进的地方。

【讨论】:

  • 大箱子甚至没有那么大。如果16*16*16 花费了 0.1 秒,那么 100*32*100 将花费大约一个半小时。
  • 我同意。我编辑了我的答案来举个例子,随着 N 的增加,N^2 * 6 上升得非常快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-09
  • 2015-08-14
  • 1970-01-01
  • 2011-03-24
  • 2018-08-16
  • 2011-07-07
  • 1970-01-01
相关资源
最近更新 更多