Calculate fps (frames per second) for iphone app - iphone

I am using an opengl es iphone application. What is the most accurate way to calculate the frames per second of my application for performance tuning?

I guess what you want is this:
// fps calculation
static int m_nFps; // current FPS
static CFTimeInterval lastFrameStartTime;
static int m_nAverageFps; // the average FPS over 15 frames
static int m_nAverageFpsCounter;
static int m_nAverageFpsSum;
static UInt8* m_pRGBimage;
static void calcFps()
{
CFTimeInterval thisFrameStartTime = CFAbsoluteTimeGetCurrent();
float deltaTimeInSeconds = thisFrameStartTime - lastFrameStartTime;
m_nFps = (deltaTimeInSeconds == 0) ? 0: 1 / (deltaTimeInSeconds);
m_nAverageFpsCounter++;
m_nAverageFpsSum+=m_nFps;
if (m_nAverageFpsCounter >= 15) // calculate average FPS over 15 frames
{
m_nAverageFps = m_nAverageFpsSum/m_nAverageFpsCounter;
m_nAverageFpsCounter = 0;
m_nAverageFpsSum = 0;
}
lastFrameStartTime = thisFrameStartTime;
}
Regards,
Asaf Pinhassi.

Try running:
Run -> Run With Performance Tool -> OpenGL ES.
You have to run that tool when connected to the device (which you'd obviously want to anyway for performance tuning...)
It gives you Core Animation FPS which may (probably) not be what you are looking for, but it can graph a number of other useful statistics for you which may also help you optimize.

Find something like a high resolution timer (more than 1000 ticks/seconds),
and measure the time between when you start rendering until it's on the screen.
Divide the ticks per second by the time you just measured, and you have the FPS.

When you reach the end of your drawing code, increase a counter.
Setup an NSTimer fire every second, display the counter, and reset it to zero.

Check this thread out. There are some very useful links on it. Good luck!

Measuring FPS during development is nearly meaningless.
Measure the rendering time you need!
This way you will have a much clearer understanding of how your changes affect performance.
Usually it's a very good idea to split your rendering time into meaningful slices, e.g. "render background", "render level", "render mobs", etc.
If you still want to do FPS my personal favourite is Johns NSTimer version, even if it doesn't show spikes.

Related

What is the consequence of doing heavy work in fixedUpdate()?

I know if I do too many thing in update() the consequence would be dropped frame rate below the target frame rate. But what would happen if I do the same thing in fixedUpdate()?
Would it cause Unity's physicsEngine to mess up, or would it crash the program?
The answers and comments were very helpful, but they lack a clear, informative answer to my question. Everyone knows bad things will happen when you put too much work load in the FixedUpdate() loop, my question was to ask what bad thing will happen then.
Since I finally got my hand on a computer I decided to make some test on my own. Just for reference this is what I used to test:
public class TestFixedUpdate : MonoBehaviour {
public int loopNo = 500000;
private int noOfCall = 0;
private int collisionTimes = 0;
private void FixedUpdate()
{
if (noOfCall > 100) return;
float time = Time.timeSinceLevelLoad;
for (int i = 0; i < loopNo; i++) {
Quaternion.Slerp(Quaternion.identity, Quaternion.FromToRotation(Vector3.up, Vector3.forward), Mathf.Abs(Mathf.Sin(Time.timeSinceLevelLoad)));
}
Debug.Log(Time.timeSinceLevelLoad.ToString("0.00"));
if (noOfCall > 99) Debug.Log("Simulation finished. Times collided:" + collisionTimes);
noOfCall++;
}
private void OnCollisionEnter(Collision collision)
{
if (noOfCall > 100) return;
collisionTimes++;
Debug.Log("Times collided:" + collisionTimes);
}
}
I put it on a sphere that will continuously bounce on a plane. The test was made by changing the function from FixedUpdate() and Update() and compare the differences.
The main difference I found out was that in the case of FixedUpdate(), Unity's simulated Time (the game world's time) is delayed out of sync with actual time. In other words, any function that depends on Unity's Time system will act as if the whole world has slowed down.
Also:
Unity reports the same frame rate for both cases, even though for the FixedUpdate() case it is apparent that the actual frame rate - the frame per real world second - is significantly lower.
Aside from slowing down, collision detection and physics simulation logic seem to work as usual. Bodies that should collide still collide; acceleration, force application etc still work. Rigidbodies that don't jump through a collider in 20ms (Unity's ms) still collide and bounce back as usual.
The Maximum Allowed Timestep option in Project's settings define the maximum amount of (Unity's simulated time) before a frame must be draw (I never knew what it was for before). Clarification: if I set it to 0.5 second, then no matter how much code I put into both functions, the logic update step (Update()) will be called immediately after a FixedUpdate() round has simulated the 0.5-th second, and then the scene will be rendered.
The engine will stall while processing a heavy load (e.g. if you do an infinite loop) inside any function. Things which rely on Time.DeltaTime will start acting up if the frame rate drops too low. It won't really matter whether that's Update or FixedUpdate.
What you can do if you need a process to run a heavy load is to use an coroutines e.g. IEnumerator function and yield, which allows you to split processing over a number of frames, or to have some function called via a callback. e.g. if you have an AI check path 5 times a second you can either handle that in Update with a counter each frame or you can schedule a callback.
Basically, there's going to be limit in how much code you can run per frame without degrading performance. Clever rewriting should make that unnecessary. See if you can cache results of calculations or pre-calculate as much data outside play as possible.

Access Terrain data more efficiently

I'm developing an editor tool for terrains. I want to do some calculation every time the terrain is modified by user.
Currently I get heightmap with these:
TerrainData tData = SketchTerrain.terrainData;
int resolution = tData.heightmapResolution - 1;
float[,] heights = tData.GetHeights(0, 0, resolution, resolution);
And then I have to check every float in the array to see if there are any changes. This works but it's slow and creates garbage and I have to do it in a fraction of a second (like 4 times per second). I also have to do it for splats too. This puts too much pressure on the CPU and results in frame rate drop.
So is there an alternative?

cocos2d starting particles from a specific time in the future

I am developing a cocos2d based app with a space background in which I am exploiting a CCQuadParticleSystem to make blinking stars. I have generated this particle system with ParticleDesigner. As soon as I load the particle system white dots representing stars start appearing in the background and after a while they fade out so that, after few seconds in which the particle system reaches the regime state, a night sky full of stars comes out.
My problem is that I would like to know if there is a way to make the particle system starting from a specific time in the future (for instance t0 = 3sec) so that I do not have to wait to have all the starts blinking.
I hope I have clearly explained the problem
thank you in advance
Andrea
I did this and it worked exactly the way I wanted it to.
for (int i = 0 ; i < 300 ; i++)
[emitter update:.1];
Have you tried a
id actions = [CCSequence actions:[CCDelayTime actionWithDuration:3.0f],
[CCCallFunc actionWithTarget:self selector:#selector(onStallComplete)],
nil];
[self runAction:actions];
ok, granted it is probably abusing the original intent of the API's , but is useful
watch for re-entrancy in onStallComplete if you have multiple such delayed reactions.
note: newbie at SO, hope the code snippet comes out looking right
I assume you are using some kind of updateWithDelta: method in your game loop in order to update the particles. If you want the particles to start after a certain interval, make your own timer.
Edit: Based on your comment below, my method is still good, it just needs some tweaking. You need only remove the condition in the updateWithDelta: method on the particle system. That way, it will still update for those 3 seconds, but will not render, and therefore look the way you are describing.
In the .h file:
BOOL particleShouldUpdate;
float particleTimer;
In your init method:
particleShouldRender = NO;
particleTimer = 3.0f;
In your updateWithDelta: method:
if(!particleShouldRender){
particleTimer -= delta;
if(particleTimer < 0){
particleShouldRender = YES;
}
}
// update your particle.
Finally, in your render method:
if(particleShouldRender){
// render your particle.
}
Note that from this point, if you want to stop it rendering, you need only reset the 2 variables like as in the init method, and the same effect will occur.
EDIT2: Upon further clarification, we only need to adapt the init method of your particle. I will make 2 assumptions here, and you need only change them slightly to fit your needs. Suppose that your update cycle is 60 frames per second, the minimum particle lifespan is 1.01, and that you want 3 seconds of updates before you start the game. Then in the init method, try:
for(float delta = 0.0f; delta < 3.0f; delta += (1/60)){
[particle updateWithDelta:(float)(1/60)];
}
This will update your particle like it normally would, but without rendering at each interval, and before anything else gets updated. Alternatively, if you are worried about speed when updating your particle, you can try:
for(int i = 0; i < 3; i++){
[particle updateWithDelta:1];
[particle updateWithDelta:0.02];
}
This will be faster, but may have a few issues depending on your particles parameters.
EDIT3: So looking into this further, cocos2D does not let you do this for some reason. I found a similar question online to this, and they suggested you play with the posVar and speed to make them large enough while you are transitioning into the scene, and once you have fully transitioned into the scene, reset the values to normal. You may want to give that a try!
Hope that Helps!
I do not think there is a way to fast forward your particle system 3 seconds into the future. Alternatively I can imagine two different solutions depending on your circumstances:
Load the scene with the particle behind another scene (e.g. an empty black scene). After 3 seconds switch to the scene with the now nice looking particle effect. This could work f it is ok for you that the user needs to wait for 3 seconds and you only do not want them to see the particle system while everything is clunked together or if you have another scene before the scene with the particle system anyway.
Record the particle system, store it in a file then replay it in your scene. With recording I mean store the position and color of each of your particles. The drawback is, that it will look the same everytime and if you want to run it longer than what you recorded you need to make sure replaying it in a loop still looks good.
I can't think of a way to implement this directly, but could you try something like this as a workaround? I'm afraid I haven't been able to test this yet due to other errors, but working on it.
{
...
//This attempts to make 3 seconds pass 100 times quicker
[[CCScheduler sharedScheduler] setTimeScale:100];
[self schedule:#selector(cancelIncreasedTimeScale) interval:3];
...
}
int numberOfTimesCancelled = 0;
-(void) cancelIncreasedTimeScale
{
numberOfTimesCancelled ++;
//Two because the scheduler is also called straight away? Remove if it's only called after waiting an initial (3/100) seconds
if (numberOfTimesCancelled == 2) {
[self unschedule:#selector(cancelIncreasedTimeScale)];
[[CCScheduler sharedScheduler] setTimeScale:1];
}
}
The issue I do worry about is the other items on your scene would also run 100 times faster. Is that an issue?

How to measure true FPS performance of OpenGL ES?

I realized that these are two different things:
Drawing, and getting it on screen.
So while you may draw in every single call from CADisplayLink at a rate of 60 FPS, if your drawing operations take slightly longer than 1/60 seconds you end up with 30 FPS in theory, because you're missing out every other chance to get through the render pipeline.
OK; Knowing this, it seems nonsense to remember the start NSTimeInterval and incrementing a frame counter in the run loop, then checking at the end if a second has passed and calculate the FPS for the last passed second.
I want a way to actually get the true FPS value from OpenGL ES on screen. I looked into instruments in Xcode 3.2.6 but couldn't find one for this. But I remember there was a way to get that FPS value. The real one.
How?
Measuring OpenGL ES performance by framerate may not be the best approach. I've taken to recording frame time myself, which seems to provide a more accurate assessment of my overall rendering performance. It's trivial to encapsulate your rendering in something like
CFTimeInterval previousTimestamp = CFAbsoluteTimeGetCurrent();
// Do your OpenGL ES frame rendering here, as well as presenting the onscreen render buffer
CFTimeInterval frameDuration = CFAbsoluteTimeGetCurrent() - previousTimestamp;
NSLog(#"Frame duration: %f ms", frameDuration * 1000.0);
to obtain rendering time. If you want it, your instantaneous framerate is the inverse of frameDuration in the above code.
Be careful to time the entire frame rendering, because the tile-based deferred renderer in iOS and other mobile devices may hide the true cost of particular rendering operations by delaying them until just before the frame is drawn to the screen.
However, if you want to obtain a less precise framerate from Instruments, you can do that using the OpenGL ES Driver instrument, which reports Core Animation Frames Per Second as one of its logged statistics:

Why is using a static int in my accelerometer callback so much slower than using an instance variable?

I'm playing with the GLGravity example to figure out some of the performance nuances related to dealing with the accelerometer.
Here's the problem code:
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
static int accelCallCount;
accelCallCount++;
if (accelCallCount % 100 == 0) {
NSLog(#"accelCallCount:%d", accelCallCount);
}
//Use a basic low-pass filter to only keep the gravity in the accelerometer values
accel[0] = acceleration.x * kFilteringFactor + accel[0] * (1.0 - kFilteringFactor);
accel[1] = acceleration.y * kFilteringFactor + accel[1] * (1.0 - kFilteringFactor);
accel[2] = acceleration.z * kFilteringFactor + accel[2] * (1.0 - kFilteringFactor);
//Update the accelerometer values for the view
[glView setAccel:accel];
}
This code runs very slowly. Visually, I can tell that the movement of the teapot becomes very delayed, and it just gets slower and slower. Eventually the teapot's movements are easily 2+ minutes delayed from the time I actually moved the device.
The output in the Debugger Console does show some delay, too, but it's not too much. It's nearly (but not quite) twice as slow as it should be.
2009-11-27 02:18:58.874 GLGravity[419:207] accelCallCount:100
2009-11-27 02:19:00.507 GLGravity[419:207] accelCallCount:200
2009-11-27 02:19:02.174 GLGravity[419:207] accelCallCount:300
Accelerometer callbacks seem to pile up, though, in some kind of queue. So what starts off as being not-too-bad quickly becomes unbearably slow.
This problem disappears, however, if I just move the declaration of accelCallCount to the header file and declare it as an instance var:
int accelCallCount;
Why does this fix it?
On a related note, whether I use this code or the "fixed" (accelCallCount as an ivar) code, the whole thing also slows down if I touch the screen. Why might that be?
Reduce the accelerometer frequency.
I reduced it to 50.0 hz and the acceleration update events stopped building up, thus improving the rendering speed. At 50hz the app runs perfect (the iPhone cannot render at 100hz anyways).
#define kAccelerometerFrequency 50.0 // Hz
You get lots of events coming through, and they are all being processed in the delegate method itself at present, on the main thread. If your message to glView is expensive as well, the system will be processing that and incoming events will be queuing up.
An option might be to batch up the events in the delegate call, then periodically process them and take the summary result and then update the display. That should give the main thread time to handle touch events as well.
So for example, add the events to an array in the delegate method, with as little code as possible in there (make the array pre-allocated block that you loop over using head and tail indexes), then every n events, deach a thread to process them and have that post back to the main thread with the glView update values (or even better, keep a background thread alive that does the processing periodically, protecting the data with a semaphore if needed).
Also, you can set the updateInterval on the accelerometer object, maybe you just need to slow it down?
As for the instance vs method static... my guess is that the instance var will be accessible all the time without overhead, but the static within the method will be comparatively expensive to access. But that is noteworthy and something I will have to watch out for as well.
Hope this helps.