I have a custom UIView which is for a GameOfLife exercise .. my board size is large enough that processing it limits "framerate". (currently this begins to kick in below the 60fps of the screen at about 100*100 in my simulator)
I am already keeping a set of only the cells that I need to calculate in each step.
But now I'd like to divide that set up into parts and thread each part. How can I do this ?
Things that I need to know:
A starter is: How can I divide the Set into n parts?
How do I determine how many threads I benefit from?
Can I use DispatchQueue.global(qos: .userInitiated) or is there some pool feature I should be using?
You can increase the frame rate and buffer performance by utilizing the underlying GPU architecture built into iOS, SceneKit & Metal rather than just rely on the CPU.
It's difficult to answer this rather broad question with the limited information provided, however I can push you in the right direction... It seems to me that you are using Single-Thread Rendering forcing the execution to be Serialized on the CPU. The underlying CPU and GPU architecture can work together to automatically run threads in parallel while still being thread safe and synchronous but learning curve to reach this point is quite high, but don't be discouraged because simple changes can greatly improve your code's performance.
"I'd like to divide that set up into parts and thread each part. How can I do this ?"
It would be advantageous to learn about Metal and the Metal Command Queue or MTLCommandQueue, utilizing the gpu and cpu together performance can be dramatically improved. There are many great tutorials on the internet that can explain it better and in more detail than I can here. In short, you can use command buffers to encode an entire scene or divide work out among threads automatically.
"how do I determine how many threads I benefit from ?"
Metal can 'automatically' control the number of threads needed to run a command, so allocating and deallocating threads 'manually' is not needed. Depending on the load and execution metal and the CPU work together to divide work out to as many threads as needed to complete the work on time.
"can I use DispatchQueue.global(qos: .userInitiated) ?"
Grand Central Dispatch is not typically used for graphics, in general GCD is used off of the main CPU thread to run concurrent code on multicore hardware unrelated to graphics. GCD doesn't utilize the GPU and Metal to run code unless it explicitly calls that code. Again There are plenty of tutorials available for GCD, but these tutorials may not improve the performance of your application as dramatically as metal command queues would. Without the code in question it would be difficult to analyze performance issues or recommend an effective solution.
There are plenty of Game of Life example on GitHub written in swift. I'd recommend you review theses and see how others are doing it, learn by example as they say.
Watch the WWDC Metal for Game Developers video from apple, this will give you a general insight on how metal performs, but without a stable underlying understanding of it you may not be able to implement its features right away.
There is a good ray wenderlich metal tutorial that can get you started using Metal and SceneKit effectively.
Related
So I've read some stuff about multithreading and NSOperation and wondering how I can use that to improve my app. Using Instruments I have isolated a few places where my app could definitely use a speed improvement. My question is, are these kinds of things suitable for another thread using NSOperation?
Drawing a view: I have a rather complex view that is taking a little time to draw. When it's drawn I experience some lag.
Allocating and playing audio: I'm using AVAudioPlayer to play some background music. When I allocate it, again some lag.
Calculations: I'm also performing some calculations and doing some comparisons with lots of integers.
I strive for the best possible performance for my app, so what would you do?
UI updates are not suitable on the Background thread. All UI updates always need to be done on the main thread. If your view is taking too much time to render, consider refactoring, pre-redering and caching or some other means of optimization.
Audio code can be background based, but shouldn't be that expensive
Calculations can definitely be backgrounded without worry.
I concur that background threads are not the thing to do for UI updates. Since the user is "blocked" on waiting for the UI to show them what is going on - it doesn't make sense from a logical point-of-view - and it can cause other coding issues.
The biggest thing I have found good for background threads often has to do with asynchronous operations. (Think of an AJAX web page). If you want your user to be able to interact with the UI while something is going on. A good example would be retreiving, updating, fetching any kind of data from the web.
Even if you are doing any kind of web operations which you would think should be synchronous - (like loading a message from a web site) - you would probibly want to handle it asynchronously because you don't know what kind of network conditions would cause it to take a long time - and perhaps eventually timeout or fail. (Something like recording audio would work like this too).
Even if you were to want to block your application when reading such a synchronous piece of data from the web, you may still want to do this asynchronously - so you could load the data in a background thread - while you give a progress bar, spinner (progress) control, or allowed the user to hit a "Cancel" button in the foreground UI thread.
Think of "asynchronous" requests as ones that will take a longer period of time - or in which you can't determine how much time it will take.
Some UI drawing methods were made thread safe with iOS 4.0:
source: Apple dev: What's new in iOS: iOS 4.0
Drawing to a graphics context in UIKit is now thread-safe. Specifically:
The routines used to access and manipulate the graphics context can now correctly handle contexts residing on different threads.
String and image drawing is now thread-safe.
Using color and font objects in multiple threads is now safe to do.
I've found that my apps generally benefit the most from background threading:
Downloading things from the web
Expensive queries (reading/writing) to the database
Long running algorithms
If you do decide to background some tasks, I would recommend using NSOperation and NSOperationQueue, as they simplify things a lot. A bit of a learning curve, but definitely worth it!
Best of luck!
My problem is understanding programming on real-time system. I'm confuse about this topic. What can I do and what I can not do in my source code? I know there are attensions to do during source code programming but I don't know exactly what. Some examples. Is possibile using dynamic memory allocation(new)? Is possible access to disk during real-time? What kind of IPC(Interprocess communication) can I use? Can I use standard interprocess locking? And what is with file locking? I have searched on internet but didn't find what I want. Where can I better understand this problems? I hope someone can help me. Sorry for my english!
You can do whatever your language/compiler of choice supports.
What you should do now, it really depends on what's the target system, what is your program (you could be writing an OS for all I know), etc...
Realtime system is all about determinacy - fixed timing for each . Check this out for some guidelines:
http://cs.brown.edu/~ugur/8rulesSigRec.pdf
What defines a real-time/near-real time system?
On the software side (your focus):
a. Avoid buffering or caching in your code. Caching are meant to speed up subsequent processing after the first, but then this result in indeterminacy of timing.
b. Minimize conditional branching, as it will generate different path resulting in different timing, this is especially important for the time-sensitive component.
c. Avoid asynchronous, or interrupt based design. Use polling whenever possible - that will increase the predictability of the timing.
d. Use a realtime OS (like LynxOS RTOS) whenever possible. It has high responsiveness and predictability in its processing. But if you look at its internals, you will see that it skips a lot of error processing, it has low threshold for maximum numbers of processes it can spawn etc. Ie, there is a lot of spare CPU computing power leftover always, to ensure that the responsiveness is there. Of course, the moment you pushed the numbers to its limits (eg, spawning lots of processes) the realtime behavior of LynxOS does not exhibit anymore.
Just lots of commonsense applied when you do coding.....
I've just started playing around with opengl es on the iphone the past couple of weeks and i'm looking at refactoring some of my code to use Vertex Buffer Objects(VBO). Before I do though I would like to make sure it'll be worth it. The problem is that afaik the only reason you create VBO's is to shift a chunk of data onto the graphics card so that it doesn't need to be retrieved from system ram when it's used. The iPhone however does not have any dedicated ram that I'm aware of so i'm struggling to see why I would benefit at all from using VBO's. I have seen talk around the internet with conflicting opinions and apple certainly want dev's to use it so there's probably still a reason to use them but just wanted to see if anyone on SO had an opinion to add.
I saw no performance improvement on an iPhone 3G. I moved a bunch of stuff to VBOs, but eventually backed it out as it made it more difficult for me to pursue other performance gains. It's not the quick 25% performance increase that I was hoping for.
I've read somewhere that it can make a difference on the newer hardware (3GS), but I don't have references to back that up.
It depends. (sorry).
Rob didn't see an improvement for his setup, but here is an interesting post that did see a large improvement.
The main reason to existence of VBO's is the presence of static data on 3D models. The first bottleneck you encounter is the slowness of copying data to video memory (by using the unavailable glBegin/glEnd block or glVertexPointer, glBufferData and friends).
Let's imagine the old "flying toaster" screensaver. All toasts are static (changing only the position) - why waste resources copying them every frame from CPU's memory to GPU's? Copy it once with buffers and draw it with a single command. And, depending on how you do animations, even the animated toasters can be described in a static fashion.
My first 2D game I started without VBOs. When I changed to VBOs, no difference (like Rob). But, when I refactored to use more static buffers, FPS gone from 20 to 40. Since my goal was to reach 30, I was satisfied. I had some ideas to refactor even more, leaving everything static, but I don't have time now (game is on review, next one to come).
I'm not sure but the iPhone has no multicore-CPU. So does it make sense to put effort into multithreading or is that just a waste of time?
I am doing some heavy stuff which lets my whole UI freeze up until that's done. Now that stuff seems to be so heavy that it just sucks up all the CPU power. Is threading a solution to at least quickly switch between two processes - the heavy stuff and responding to user interaction?
Yes, it does make sense to have multiple threads. Specially if you are performing some kind of I/O (disk, network), your application will be much more responsive if you don't block while waiting for input or output to happen.
Even if your CPU if 100% consumed by your application, UI will still respond and not freeze if you do your heavy computation in a separate thread.
You don't need multiple cores to take advantage of multi-threading (multi-threading has been around a lot longer than multi-core CPUs).
It will allow you to start processes in the background so that your UI remains responsive, thus leading to an improved User Experience with your application.
...so yes, put the effort in to multithreading.
Yes, because you never know, at some point, there may be a multicore cpu in an iPhone (if there isn't now), and your app will support it.... ;)
What are the best practices, tricks, and tutorials for using XCode's performance tools, such as the Leak Monitor and the CPU sampler, for someone trying to debug and enhance performance of an iPhone application?
Thanks!
It depends entirely on the application and on what you are trying to do. Are you trying to optimize the whole application or are you focused on a particular problem area? Are you trying to reduce memory usage, reduce CPU usage, and/or make the app more responsive?
Before you start the performance analysis, use the static analyzer to analyze your code. It will often find memory management problems that would lead to leaks that would cause your app to potentially crash on the device.
Once all of the analyzer identified problems have been fixed, the best approach is to start by identifying perceived performance problems. That is, focus on performance problems that the user would notice. Then analyze those. If you can get away with it, do the analysis on the app running in the simulator as the turnaround time is faster.
If the problem is one of bloat, use Object Alloc and Leaks to figure out why.
If it is one of laggy/sluggish behavior, use the CPU tools to figure out where the cycles are going. Keep in mind, though, that sluggish behavior may not be because of CPU usage, but may be because the main event loop is blocked by something, most likely incorrect concurrency patterns. In that case, you'll see all samples on the main thread in some kind of a lock or wait function.
Beyond that, you'll need to identify specific scenarios to yield specific answers.
use instruments in that use
object allocation
activity monitor,
leaks
memoer monitor
and test your app