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.... ;)
Related
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.
I am trying to figure out how to use a background thread to execute a command ever 4hrs.
I have never created anything like this before so have only been reading about it so far.. One of the things I have read are this
"Threads tie up physical memory and critical system resources"
So in that case would it be a bad idead to have this thread that checkes the time then executes my method... or is there a better option, I have read about GCD (Grand Central Dispatch) but I am not sure if this is applicable as I think its more for concurrent requests? not something that repeats over and over again checking the time..
Or finally is there something I have completely missed where you can execute a request every 4hrs?
Any help would be greatly appreciated.
There is a max time background processes are allowed to run (10 min) which would make your approach difficult. Your next best attempt is to calculate the next event as save the times tamp somewhere. Then if the app is executed at or after that event it can carry out whatever action you want.
This might help:
http://www.audacious-software.com/2011/01/ios-background-processing-limits/
I think that it would be good to make use of a time stamp and post a notification for when the time reaches for hours from now.
Multithreading is not a good means to do this because essentially you would be running a loop for four hours eating clock cycles. Thanks to the magic of operating systems this would not eat up an entire core or anything silly like that however it would be continuously computed if it was allowed to run. This would be a vast waste of resources so it is not allowed. GCD was not really meant for this kind of thing. It was meant to allow for concurrency to smooth out UI interaction as well as complete tasks more efficiently, a 4hr loop would be inefficent. Think of concurrency as a tool for something like being able to interact with a table while its content is being loaded or changed. GCD blocks make this very easy when used correctly. GCD and other multithreading abilities give tools to do calculations in the background as well as interact with databases and deal with requests without ever affecting the users experience. Many people whom are much smarter then me have written exstensively on what multithreading/multitasking is and what it is good for. In a way posting a message for a time would be method of multitasking without the nastiness of constantly executing blocks through GCD to wait for the 4 hr time period, however it is possible to do this. You could execute a block that monitored for time less then the max length of a threads lifetime then when the threads execution is over dispatch it again until the desired time is achieved. This is a bad way of doing this. Post a notification to the notification center, its easy and will accomplish your goal without having to deal with the complexity of multithreading yourself.
You can post a notification request observing for a time change and it will return its note, however this requires you application be active or in the background. I can not guarantee the OS wont kill your application however if it is nice and quiet with a small memory footprint in "background" state its notification center request will remain active and function as intended.
I am working on a Windows game and while rendering, some computers will experience intermittent pauses ("hitches" for lack of a better term). When profiled they appear in seemingly random places in the code. Eventually I noticed that it wasn't just my process that was affected, but (seemingly) every process on the system. All of the threads in my application hitch at once. The CPU utilization drops during these hitches and it appears as if most processes make no progress.
This leads me to believe this may be an Operating System or Driver issue, but it only occurs while playing the game (and only on some systems). What sort of operations might the operating system be doing that would require the kernel to pause all user threads and block. Some kind of I/O? At first I thought of paging but my impression is that would only affect a single process, no?
Some systems in use: Windows, DirectX (3d), nVidia cards (unknown if replicates on ATI), using overlapped io for streaming
If you have a lot of graphics in use, it may be paging graphics memory into the swap file.
Or perhaps the stream is getting buffered on disk?
It's worth seeing if the hitches coincide with the PC's disk activity LED.
Heavy use of memory mapped IO. This of course includes the system pagefile, but can also include user applications that use mmio heavily (gcc for one)
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.....