我为我的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 ,但我认为没关系。
答案 0 :(得分:1)
用int
替换uint16_t
应该没有任何区别(它会占用更少的内存,但不应影响大多数计算机上的运行时间。)
显示的代码看起来已经非常快了(它只做它需要做的事情,并且没有特别的错误),我看不出你如何进一步优化它(至多你可以删除对mFirstTime
的检查,但这应该没有区别。)
如果它很慢,那是因为别的东西。也许你有太多的掉落,或者你的其余代码太慢,update
每秒被调用很少次。
我建议你描述你的程序,看看大部分时间花在哪里。
修改强>:
有一件事可以加速这样的算法,特别是如果你的系统没有FPU(那不是个人计算机的情况......),将用整数替换你的浮点值。
将elapsed
变量(和你的常量,如0.1
)乘以1000,使它们代表毫秒,并且只在整个地方使用整数。
答案 1 :(得分:1)
几点:
此外,您可以非常简单地优化所有这些,因为您不需要使用积分求解运动方程,因为它可以非常简单地直接解决:
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 * elapsed
和Gravity * 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时间过去很容易。