Original Post
Hi,
after trying to use instancing for my particle system (it's not really working right now but thats another topic) I noticed a great improve in the frameraterate. Say from first 3 FPS with 100.000 particels before I now got around 50 fps (in release mode). I know, measuring in FPS isn't the best way, so let's say the frame know takes around 50 ms to compute, while before it took 333 ms. Quite a whole lot of an improvement! Well I knew that there was still more, because my code for doing the world transformation was kind of messed up. While trying to clean up, I noticed I deleted the call for transforming the particles. I put it in again, and quess what: My framerate dropped back to 13 FPS. I did some profiling and found out that, as I expected, a whole lot of time was spent setting the transformation for each particle. That was the code before the optimizations:
I know I did a lot of unnecessary stuff, like doing translation/rotation/etc.. every time, even if the paramters didn't change. The I used SetTransform which should take some performance, and lateron called GetTransform, which I evaded storing all the matrix data as members of the CObject class (from which my particels inherit). So now the code is looking like this:
I excluded a lot of unnecessary calculations, not only in that code, but in the emitter too (like calculations I accidently performed per-particle, even if they could have been done one time per frame). However, this is what I got afterwards: 15 FPS. Well its not that bad keeping in mind how low the framerate is, but its not as I expected. I profiled again, and now, although the time taken by matrix-calculations significaty lowered (they where taking up to 25% of CPU-time before, know its only about 5% maximum), the updating of the particles still takes a lot of time. So now the obvious performance-killer lies here:
When I don't call Update() on any particle, framerate goes up to 37. Excluding SetWorldTransform makes the framerate rise up to 22-23, and excluding Move() makes it go up to 17. Excluding both somehow makes the framerate only go up to 30, only if I also exclude both the velocity and time calculation, everything is fine.
So, does anyone know what I can do? Is it a fault from me, or is it something I have to live with? 100.000 particles are not less, but I'm not even using a vector or map but an array, which should be faster from all that I know. Note: I'm using a particlesystem that doesn't delete particles after a certain amount of time and replaces them but rather "resets" old particles. So there is no performance cap from inserting/deleting elements, and the reseting doesn't take any time (I tried excluding it and it doesn't give me a single frame). Is there any way I can further optimize my transformations, or is it maybe any bug deeper in my system? Looping through all of the particles takes some time (if I exclude the complete loop I get about 120 FPS), but drawing doesn't do much, as this problem is clearly a limitiation of my CPU. Any ideas pls?
after trying to use instancing for my particle system (it's not really working right now but thats another topic) I noticed a great improve in the frameraterate. Say from first 3 FPS with 100.000 particels before I now got around 50 fps (in release mode). I know, measuring in FPS isn't the best way, so let's say the frame know takes around 50 ms to compute, while before it took 333 ms. Quite a whole lot of an improvement! Well I knew that there was still more, because my code for doing the world transformation was kind of messed up. While trying to clean up, I noticed I deleted the call for transforming the particles. I put it in again, and quess what: My framerate dropped back to 13 FPS. I did some profiling and found out that, as I expected, a whole lot of time was spent setting the transformation for each particle. That was the code before the optimizations:
void CObjects::SetWorldTransformation(void)
{
D3DXMATRIX WorldMatrix, RotationMatrixX, RotationMatrixY, RotationMatrixZ, TranslationMatrix, ScaleMatrix, ViewMatrix, ProjectionMatrix;
float RotationX, RotationY, RotationZ = 0.0f;
if(m_Rotation.x == 0.0f)
m_Rotation.x = 360.0f;
RotationX = DEGTORAD(m_Rotation.x);
if(m_Rotation.y == 0.0f)
m_Rotation.y = 360.0f;
RotationY = DEGTORAD(m_Rotation.y);
if(m_Rotation.z == 0.0f)
m_Rotation.z = 360.0f;
RotationZ = DEGTORAD(m_Rotation.z);
D3DXMatrixRotationX(&RotationMatrixX, RotationX);
D3DXMatrixRotationY(&RotationMatrixY, RotationY);
D3DXMatrixRotationZ(&RotationMatrixZ, RotationZ);
D3DXMatrixScaling(&ScaleMatrix, m_Scale.x, m_Scale.y, m_Scale.z);
D3DXMatrixTranslation(&TranslationMatrix, 0.0f, 0.0f, 0.0f);
D3DXMatrixMultiply(&WorldMatrix, &ScaleMatrix, &TranslationMatrix);
D3DXMatrixMultiply(&WorldMatrix, &WorldMatrix, &RotationMatrixZ);
D3DXMatrixMultiply(&WorldMatrix, &WorldMatrix, &RotationMatrixX);
D3DXMatrixMultiply(&WorldMatrix, &WorldMatrix, &RotationMatrixY);
D3DXMatrixTranslation(&TranslationMatrix, m_Position.x, m_Position.y, m_Position.z);
D3DXMatrixMultiply(&WorldMatrix, &WorldMatrix, &TranslationMatrix);
m_lpDevice->SetTransform(D3DTS_WORLD, &WorldMatrix);
m_lpDevice->GetTransform(D3DTS_VIEW, &ViewMatrix);
m_lpDevice->GetTransform(D3DTS_PROJECTION, &ProjectionMatrix);
WorldMatrix = WorldMatrix * ViewMatrix * ProjectionMatrix;
m_World = WorldMatrix;
}I know I did a lot of unnecessary stuff, like doing translation/rotation/etc.. every time, even if the paramters didn't change. The I used SetTransform which should take some performance, and lateron called GetTransform, which I evaded storing all the matrix data as members of the CObject class (from which my particels inherit). So now the code is looking like this:
void CObjects::SetWorldTransformation(void)
{
m_WorldMatrix = m_ScaleMatrix;
m_WorldMatrix *= m_RotationMatrixZ;
m_WorldMatrix *= m_RotationMatrixX;
m_WorldMatrix *= m_RotationMatrixY;
m_WorldMatrix *= m_TranslationMatrix;
m_lpDevice->GetTransform(D3DTS_VIEW, &m_ViewMatrix);
m_lpDevice->GetTransform(D3DTS_PROJECTION, &m_ProjectionMatrix);
m_World = m_WorldMatrix;
m_ViewMatrix *= m_ProjectionMatrix;
m_World *= m_ViewMatrix;
}I excluded a lot of unnecessary calculations, not only in that code, but in the emitter too (like calculations I accidently performed per-particle, even if they could have been done one time per frame). However, this is what I got afterwards: 15 FPS. Well its not that bad keeping in mind how low the framerate is, but its not as I expected. I profiled again, and now, although the time taken by matrix-calculations significaty lowered (they where taking up to 25% of CPU-time before, know its only about 5% maximum), the updating of the particles still takes a lot of time. So now the obvious performance-killer lies here:
void CParticle::Update(void)
{
m_Velocity.y -= m_Gravity;
m_Time += 1;
Move(m_Velocity.x + cos((float)m_Time/4)/4*m_Float.x, m_Velocity.y, m_Velocity.z + cos((float)m_Time/4)/4*m_Float.y);
SetWorldTransformation();
}
void CObjects::Move(float X, float Y, float Z)
{
m_Position.x += X;
m_Position.y += Y;
m_Position.z += Z;
D3DXMatrixTranslation(&m_TranslationMatrix, m_Position.x, m_Position.y, m_Position.z);
}When I don't call Update() on any particle, framerate goes up to 37. Excluding SetWorldTransform makes the framerate rise up to 22-23, and excluding Move() makes it go up to 17. Excluding both somehow makes the framerate only go up to 30, only if I also exclude both the velocity and time calculation, everything is fine.
So, does anyone know what I can do? Is it a fault from me, or is it something I have to live with? 100.000 particles are not less, but I'm not even using a vector or map but an array, which should be faster from all that I know. Note: I'm using a particlesystem that doesn't delete particles after a certain amount of time and replaces them but rather "resets" old particles. So there is no performance cap from inserting/deleting elements, and the reseting doesn't take any time (I tried excluding it and it doesn't give me a single frame). Is there any way I can further optimize my transformations, or is it maybe any bug deeper in my system? Looping through all of the particles takes some time (if I exclude the complete loop I get about 120 FPS), but drawing doesn't do much, as this problem is clearly a limitiation of my CPU. Any ideas pls?