帮助代码优化

时间:2010-12-31 11:18:47

标签: c++ optimization

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

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

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

但是这段代码的工作速度慢于我所有的代码。请帮我优化一下。

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

6 个答案:

答案 0 :(得分:1)

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

显示的代码看起来已经非常快了(它只做它需要做的事情,并且没有特别的错误),我看不出你如何进一步优化它(至多你可以删除对mFirstTime的检查,但这应该没有区别。)

如果它很慢,那是因为别的东西。也许你有太多的掉落,或者你的其余代码太慢,update每秒被调用很少次。
我建议你描述你的程序,看看大部分时间花在哪里。


修改
有一件事可以加速这样的算法,特别是如果你的系统没有FPU(那不是个人计算机的情况......),将用整数替换你的浮点值。

elapsed变量(和你的常量,如0.1)乘以1000,使它们代表毫秒,并且只在整个地方使用整数。

答案 1 :(得分:1)

几点:

  1. 物理学是不正确的:风速应该随着速度接近风速而改变,同样为了简单起见我会假设x_speed的初始值是风的速度。
  2. 你根本不注意风的分数,因此滴水变得越来越快。但这取决于你想要建模。
  3. 我只是假设跌落在恒定速度下以恒定速度失败,因为这确实是非常快速发生的事情。
  4. 此外,您可以非常简单地优化所有这些,因为您不需要使用积分求解运动方程,因为它可以非常简单地直接解决:

    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;
    

    如果您想对下降速度越来越快的模型进行建模。

答案 2 :(得分:1)

很少有事情需要考虑:

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

update函数中,不是为每次迭代计算windPower * elapsedGravity * elapsed,而是在循环之前计算并保存,然后添加。此外,重新组织循环,没有必要进行速度计算并渲染如果丢弃超出屏幕,先进行检查,如果丢弃仍在屏幕中,则更新速度并渲染!

有趣的是,你永远不会检查掉落是否超出它x坐标的屏幕内部,你检查高度,而不是宽度,如果你做了这个检查,你可以节省一些计算和渲染时间还有!

答案 3 :(得分:0)

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

BTW我认为在mFirstTime中咨询processDrops没有任何意义,因为它永远不会成真。嗯,我在初始化循环中错过了processDrops。别介意。

答案 4 :(得分:0)

这对我来说已经非常快了。 您可以通过删除“firsttime”代码并将其置于其自己的函数中来获得一些微小的加速,以便调用一次而不是测试每个调用。

您正在对大量类似数据进行相同的计算,因此您可以考虑使用SSE内在函数一次处理多个项目。你可能不得不重新安排你的数据结构虽然是矢量结构而不是像现在这样的矢量od结构。我怀疑它会有多大帮助。你的载体中有多少项?

答案 5 :(得分:0)

看起来好像你的所有时间都进入... Drawing Here find out for sure时间过去很容易。