【问题标题】:Help with code optimization帮助代码优化
【发布时间】:2010-12-31 22:14:23
【问题描述】:

我为我的二维应用程序编写了一个小粒子系统。这是下雨的代码:

// HPP -----------------------------------
struct Data
{
    float x, y, x_speed, y_speed;
    int timeout;
    Data();
};        
std::vector<Data> mData;
bool mFirstTime;
void processDrops(float windPower, int i);

// CPP -----------------------------------
Data::Data()
    : x(rand()%ScreenResolutionX), y(0)
    , x_speed(0), y_speed(0), timeout(rand()%130)
{ }

void Rain::processDrops(float windPower, int i)
{
    int posX = rand() % mWindowWidth;

    mData[i].x = posX;

    mData[i].x_speed = WindPower*0.1; // WindPower is float
    mData[i].y_speed = Gravity*0.1;   // Gravity is 9.8 * 19.2

    // If that is first time, process drops randomly with window height
    if (mFirstTime)
    {
        mData[i].timeout = 0;
        mData[i].y = rand() % mWindowHeight;
    }
    else
    {
        mData[i].timeout = rand() % 130;
        mData[i].y = 0;
    }
}

void update(float windPower, float elapsed)
{
    // If this is first time - create array with new Data structure objects
    if (mFirstTime)
    {
        for (int i=0; i < mMaxObjects; ++i)
        {
            mData.push_back(Data());
            processDrops(windPower, i);
        }
        mFirstTime = false;
    }

    for (int i=0; i < mMaxObjects; i++)
    {
        // Sleep until uptime > 0 (To make drops fall with randomly timeout)
        if (mData[i].timeout > 0)
        {
            mData[i].timeout--;
        }
        else
        {
            // Find new x/y positions
            mData[i].x += mData[i].x_speed * elapsed;
            mData[i].y += mData[i].y_speed * elapsed;

            // Find new speeds
            mData[i].x_speed += windPower * elapsed;
            mData[i].y_speed += Gravity * elapsed;

            // Drawing here ...

            // If drop has been falled out of the screen
            if (mData[i].y > mWindowHeight) processDrops(windPower, i);
        }
    }
}

所以主要思想是:我有一些结构,包括下降位置、速度。我有一个处理向量数组中某个索引处的滴的功能。现在,如果这是第一次运行,我正在制作具有最大大小的数组并循环处理它。

但是这段代码的运行速度比我拥有的所有其他代码都要慢。请帮我优化一下。

我尝试将所有 int 替换为 uint16_t 但我认为没关系。

【问题讨论】:

  • 可能超时没那么高效,但是不知道“update()”函数是怎么调用的
  • @Cristy 我不知道如何让水滴随不同时间移动。
  • @Cristy,更新函数调用每帧更新(例如~17 ms)
  • 也许为每一滴做不同的速度:),brb午餐时间:D
  • 您没有说要模拟多少雨滴,但假设这是合理的,那么唯一会超过 17 毫秒窗口的代码就是您省略的绘图代码。另外,也许代码运行正常,但雨滴的速度很慢?最好剖析一下,看看瓶颈在哪里。

标签: c++ optimization


【解决方案1】:

uint16_t 替换int 应该没有任何区别(它会占用更少的内存,但不会影响大多数机器上的运行时间)。

显示的代码看起来已经相当快了(它只是在做它需要做的事情,并且没有特别的错误),我不知道你可以如何进一步优化它(最多你可以取消对mFirstTime 的检查,但这应该没有区别)。

如果它很慢,那是因为其他原因。也许你的丢包太多了,或者你的其余代码太慢了,以至于 update 每秒被调用的次数很少。
我建议您对您的程序进行概要分析,看看花费最多的时间。


编辑
可以加速这种算法的一件事,特别是如果您的系统没有 FPU(!个人计算机不是这种情况......),就是用整数替换您的浮点值。

只需将 elapsed 变量(以及您的常量,如 0.1)乘以 1000,这样它们就可以表示毫秒,并且在任何地方都只使用整数。

【讨论】:

    【解决方案2】:

    几点:

    1. 物理学不正确:风力应随着速度接近风速而改变,同样为简单起见,我假设 x_speed 的初始值是风速。
    2. 你根本不关心风的分数,所以下降的速度越来越快。但这取决于您想建模。
    3. 我只是假设在恒定方向上以恒定速度下降失败,因为这确实发生得非常快。

    您也可以非常简单地优化这一切,因为您不需要使用积分来求解运动方程,因为它可以直接求解:

    x(t):= x_0 + wind_speed * t
    y(t):= y_0 - fall_speed * t
    

    这是当重力等于摩擦力时稳定下落的情况。

    x(t):= x_0 + wind_speed * t;
    y(t):= y_0 - 0.5 * g * t^2;
    

    如果您想对下落越来越快的水滴进行建模。

    【讨论】:

    • 感谢您的想法,我会审查它。
    【解决方案3】:

    需要考虑的几件事:

    在您的processDrops 函数中,您传入了windPower,但使用了某种名为WindPower 的类成员或全局变量,这是错字吗?如果Gravity 的值没有变化,则保存计算(即乘以 0.1)并直接使用。

    在您的update 函数中,不是为每次迭代计算windPower * elapsedGravity * elapsed,而是在循环之前计算并保存它,然后添加。另外,重新组织循环,如果水滴超出屏幕,则无需进行速度计算和渲染,先检查,如果水滴仍在屏幕中,则更新速度并渲染!

    有趣的是,您从不检查下降是否超出屏幕的 x 坐标,您检查的是高度,而不是宽度,如果您进行此检查,您可以节省一些计算和渲染时间也!

    【讨论】:

      【解决方案4】:

      在循环中引入引用Data&amp; current = mData[i] 并使用它代替mData[i]。并在procesDrops 中使用此引用而不是索引。

      顺便说一句,我认为在processDrops 中咨询mFirstTime 毫无意义,因为它永远不会是真的。 嗯,我在初始化循环中错过了processDrops。没关系。

      【讨论】:

      • 如果这真的有所作为,请更改编译器! ://
      • 在调试构建中,其他一些事情比性能更重要
      【解决方案5】:

      这在我看来已经相当快了。 您可以通过删除“第一次”代码并将其放入它自己的函数中调用一次而不是测试每个调用来获得一些微小的加速。

      您正在对大量相似的数据进行相同的计算,因此也许您可以考虑使用 SSE 内在函数一次处理多个项目。您可能必须重新排列您的数据结构,使其成为向量结构,而不是像现在这样的向量 od 结构。我怀疑它会帮助太多。无论如何,您的向量中有多少项?

      【讨论】:

        【解决方案6】:

        看起来你可能所有的时间都花在... Drawing Here上。
        很容易find out for sure 时间在哪里。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-23
          • 2017-04-12
          • 2020-04-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多