I am struggling to understand the key differences between DispatchSourceTimer, Timer and asyncAfter (in my case for scheduling a task that needs to be ran every X seconds, although understanding the differences in timers can be useful to) (Or is there another (more efficient) scheduling mechanism in Swift besides the listed timers?).
A Timer needs an active run loop on the current queue it was started on. A DispatchSourceTimer does not need that. A Timer keeps the CPU from going into the idle state. Does this apply to DispatchSourceTimer/asyncAfter as well?
In what situation a Timer is preferred over a DispatchSourceTimer/asyncAfter? And of course the difference between all of them?
I want to schedule work every 15 seconds in my application on a private queue. This means I have to use DispatchSourceTimer because I am on a queue that is not the main thread (or add a runloop to the queue and use Timer). However, I do not see any benefit of even using a Timer in the first place. Maybe there is another operation that I can use that schedule work every X seconds on a private queue that is more efficient than a DispatchSourceTimer, but I did not came across a better solution.
Is a DispatchSourceTimer more efficient than a Timer? Or should I go on a self-calling method with asyncAfter?
This is the code to create the timers.
asyncAfter
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(2)) {
// Code
}
Timer
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
// Code
}
DispatchSourceTimer
let timer = DispatchSource.makeTimerSource()
timer.schedule(deadline: .now() + .seconds(1))
timer.setEventHandler {
// Code
}
timer.activate()
Whats are the cons and pros of all the timers? When should I use one above the other? What timer way is the most efficient? I came up with the following:
Timer
Pros:
Can be invalidated
No reference needed
Can be stopped while it is scheduled.
Cons:
Prevents CPU to go idle
Needs to be run on a queue with a run loop (else nothing happens, even no assertion trigger...)
DispatchSourceTimer
Pros:
Can be cancelled
No run loop needed
Cons:
Needs a strong reference else it gets deallocated instantly
asyncAfter
Pros:
- No run loop needed
Cons:
- Can not be cancelled (I think)
Are there even more timers? Why are there so many timers? I expected some real difference across all the different timers, but I couldn't find them.
Alot of questions here as you can read. The main question is: what timers are available and what timers should I use in what case and why?
Timer is a Swift bridge of NSTimer, which goes back to NeXTSTEP, long, long before Grand Central Dispatch (GCD) and things like DispatchSourceTimer, which didn't come along until 10.6 (in the form of dispatch_source_set_timer) and dispatchAfter (in the form of dispatch_after).
NSTimer is based on the run loop, which was the primary way that concurrency was done until GCD. It's a cooperative concurrency system, designed primary to run on a single thread on a single core (though it can be expanded to multi-threaded environments).
While the run loop is still very important in Cocoa, it is no longer the primary, or even preferred, way to manage concurrency. Since 10.6, GCD has been the increasingly preferred approach (though adding a block-based NSTimer API in the 10.12 timeframe was a welcome modernization).
On the scale of 15 seconds, the efficiency differences are pretty irrelevant. That said, I don't understand your comment "A Timer keeps the CPU from going into the idle state." I don't believe that's true. The CPU will definitely still go into the idle state when waiting on an NSTimer to fire.
I would not set up a run loop just to run an NSTimer. You would be much better off scheduling it on the main runloop and then using DispatchQueue.async to do the actual work on some other queue.
As a broad rule, I use the highest-level tool that meets the need. Those are the ones that Apple is likely to optimize the best over time with me making the fewest changes. For example, NSTimer fire dates are automatically adjusted to improve energy efficiency. With DispatchSourceTimer, you get control over the leeway setting to get the same benefit, but it's up to you to set it (the default is zero, which has the worst energy impact). Of course, the reverse is also true. DispatchSourceTimer is the lowest level and gives you the most control, so if that's what you need, that's the one to use.
For your example, I'd personally probably use a Timer and just dispatch to the private queue as part of the block. But a DispatchSourceTimer would be completely appropriate.
asyncAfter is really a different thing, since it's always a one-shot. That's great if you want a one-shot, but it changes things if you want to repeat. If you just call asyncAfter in the block to repeat, it's going to be 15 seconds after the last time you finished, rather than being spaced 15 seconds apart. The former will tend to drift a bit late over time. The design question is this: if for some reason your task took 5 seconds to complete, would you want the next fire event to happen 15 seconds from the end of that, or would you want a constant 15 seconds between each fire event? Your choice there will determine which tool is correct.
As a slight note there, NSTimer events are always a little later than they are scheduled. GCD events with a leeway setting can be a little early or a little late. As a practical matter, there's no such thing as being "on time" (that's a period of zero length; you're not going to hit it). So the question is always whether you are promised to be late like NSTimer, or you might be early like GCD with leeway.
Related
I have a serial OperationQueue whose operations call usleep. I do this because the operation execution block synchronizes with a Timer that needs to repeat until a designated time.
For example, 3 operations are added to a queue with a maxconcurrent set to 1. Each operations has a timer that repeats until 10 seconds into the future. Upon firing this timer of the first operation, the next line of code is usleep(10seconds). 10 seconds later the timer completes and the thread wakes up. The next operation begins. This is done by design and works, however, I'm concerns about the implications about a sleeping thread. Is it possible that the thread was handling some other code, context switches to handle the operation, then sleeps for a long time, pausing other executions. Does swift know to let the thread execute other blocks while the operation sleeps?
Does swift know to let the thread execute other blocks while the operation sleeps?
Maybe it’s just a wording issue, but the thread is blocked until the sleep (and subsequent tasks) finish, so it’s not going to be made available to do anything else. But, while the thread is sleeping, the core can switch contexts to let some other thread run even though the thread running the operation is tied up.
So using usleep (or I might use Thread.sleep(forTimeInterval: 10)) avoids the problem of blocking the core, but it still blocks the thread. And threads are rather limited (e.g. 64 at this point). So, especially if you might have a lot of these operations going on at any given time, thereby risking exhausting the limited threads, I might advise avoid blocking the thread, too. (Then again, if you’re using a maxConcurrentOperationCount of 1, as long as you aren’t doing other things that might tie up threads, it probably wouldn’t be too serious of a problem.)
For example, I might define an asynchronous Operation subclass, and rather than sleeping, I might just asyncAfter (or use a timer) the finishing of the operation to 10 seconds in the future. That way no thread is blocked, either. Or I might consider other patterns to solve the broader problem. It’s hard to say without knowing the broader problem that you’re trying to solve.
To be honest, I don't know if there might be a solution to my question but I'd like to catch, in Swift, when a context switch is happening.
I was imaging a func which takes a long time in order to be completed such as a write operation on a remote server and I was thinking if there might be a way to understand when (which line at least) the thread which is executing that task is performing a context switch because another task waiting for a long time has to be executed.
Sorry if for you might seem a stupid question or if I made mistakes whilst trying to explain the above
EDIT:
I'm talking about context switches that are happening automatically requested by the scheduler.. So imagine again we are in the middle of this long function which does tons of operations and the scheduler gave this task an amount of seconds, for example 10 seconds in order to make it complete. If the process runs out of time and doesnt end the task, it will be suspended and for example the thread will execute another task of another process. When it ends, scheduler might think to give another try to the suspended job and the execution will be resumed starting where it has been suspended ( so will read the value from PC register and will keep going on )
You can absolutely get what you've asked for, but I have a feeling it's going to be much less useful to you than you may believe. The vast (vast, vast!) majority of context switches are going to occur at points that you probably would think of as "uninteresting." lstat64(), mach_vm_map_trap(), mach_msg_trap(), mach_port_insert_member_trap(), kevent_id(), the list goes on. Most threads spend most of their time deep in the OS stack. "A write operation on a remote server" isn't going to block after it takes some long period of time. It's going to proactively block itself because it knows it's going to take a (mind-bogglingly) long period of time.
Even so, you can certainly explore this with Instruments. Just choose the System Trace profile and it'll show you all the threads and the system cores and how your threads and all the other threads on the device are getting scheduled, every system call, etc etc etc. It's a huge amount of information, so you usually only profile for a few seconds at a time. But it'll look something like this:
This is useful information if you're at the point where context switches are a major bottleneck. This might happen if you're dealing with excessive lock contention, or if you're thrashing your L1 cache because you keep getting interrupted by some other thread. So if you have some thread that you expect to stay running pretty continuously, and it's getting blocked, this is really valuable information. Or if you have two threads that you think should work back and forth smoothly, but they seem to be fighting (switching rapidly), then that's something you could work on. (But this is rarely one of the first places you'd look for performance tuning unless you're working on quite low-level code.)
From your description, I think you may have the wrong idea about the scheduler. Nothing in the scheduler is going to be on the order of 10 seconds. In the scheduler world, milliseconds are a lot of time. You should be thinking about things that take microseconds and even nanoseconds. If you're working on code that assumes fetching data from RAM is free, then you're on the wrong time scale. A network call is so ludicrously slow that you can basically estimate it as "forever." At the context-switch level you're looking at events like:
00:00.770.247 Virtual memory Zero Fill took 10.50 µs small_free_list_add_ptr ← (31 other frames)
I think its a kinda cool question but not clear.The answer is all about my understanding on your question. Normally if you implement C++ or C program for context switching, consider you write code with mutexes or semaphores.In these sections processes or threads work in critical section and sometimes there executing the context switching manually or interruption way. In iOS there are same identical implementation on concurrency such as DispatchSemaphore.(Actually mutex is a Semaphore that working with lock system.) You can read the documentation from here.
For starting to this, this is the Semaphore class definition in Swift.
class DispatchSemaphore : DispatchObject
You can init it with int value such as
let semaphore = DispatchSemaphore(value: intValue)
And if you want to use mutex variant you can easily use lock variable. Such as
var lock = Lock()
When you lock the thread with correct implementation, you will be in critical section and you can switch it with unlock or etc.
It's obviously look similar with POSIX pthread_lock_t
You can handle the context switching within the lock or semaphore critical section like that
lock.lock()
// critical section
// handle the calculation, if its longer unlock, or let it do its job
lock.unlock()
semaphore.wait(timeout: DispatchTime.distantFuture)
// critical section
// handle the calculation, if its too long signal to exit it in here, or let it do its job
// if it is a normal job, it will be signal for exit already.
semaphore.signal()
The handled answer is contains context switching in threads.
Addition to my question, when you ask about the context switching, its natural means is that changing the threads or processes basically. So when you get the data from background thread and then implement it for the UITableView' you probably will do reloadData method call in DispatchQueue.main.async . Its a common usage of context switching.
I'm working on a game sim and want to speed up the match simulation bit. On a given date there may be 50+ matches that need simulating. Currently I loop through each and tell them to simulate themselves, but this can take forever. I was hoping
1) Overlay a 'busy' screen
2) Launch a thread for each
3) When the last thread exits, remove the overlay.
Now I can do 1 & 2, but I cannot figure out how to tell when the last thread is finished, because the last thread I detach may not be the last thread finished. What's the best way to do that?
Also, usually threads are used so that work can be done in the background while the user does other stuff, I'm using it slightly different. My app is a core-data app and I want to avoid the user touching the store in other ways while i'm simulating the matches. So I want single-threading most of the time, but then multithreading for this situation because of how long the sim engine takes. If someone has other ideas for this approach I'm open.
Rob
Likely you want to use NSOperation and NOT 50 threads - 50 threads is not healthy on an iPhone, and NSOperations are easier to boot. It may be that you are killing performance (it would be my guess) by trying to run 50 at once. NSOperation is designed for exactly this problem. Plus its easy to code.
My only problem with NSOperation is that they don't have a standard way to tell the caller that they are done.
You could periodically poll the NSOperationQueue - when its count is 0 there are none left. You could also make each operation increment some counter - when the count is 50 you are done. Or each operation could post a notification using performSelectorOnMainThread on the main thread that its done.
You should see a boost in performance with even a single core - there are lots of times that the main thread is blocked waiting for user input/graphics drawing/etc. Plus multicore phones and iPads will likely be out within a year (total guess - but they are coming).
Also make sure you look at the operation with Instruments. It may be that you can speed the calculations up be a factor of 2 or even 10x!
You're on a single core, so threading probably won't help much, and the overhead may even slow things down.
The first thing to do is use Instruments to profile your code and see what can be sped up. Once you've done that you can look at some specific optimizations for the bottle necks.
One simple approach (if you can use GCD) is dispatch_apply(), which'll let you loop over your matches, automatically thread them in the best manner for your hardware, and doesn't return until all are complete.
Most straightforward solution would be to have all your threads 'performSelectorOnMainThread' to a particular method that decrements a counter, before they exit. And let the method remove the overlay screen when the counter it decremented reaches zero.
Simulating all the matches concurrently may not necessarily improve performance though.
You may get the solution for your specific question from #drowntoge, but generally, I want to give you advice about multithreading:
1/ It is not always speed up your program like Graham said. Your iPhone only has single core.
2/ If your program has some big IO, database or networking process that takes time, then you may consider multithreading because now data processing does not take all the time, it needs to wait for loading data. In this case, multithreading will significantly boost up your performance. But you still need to be careful because thread switching has overhead.
Maybe you only need 1 thread for IO processing and then has a cache layer to share the images/data. Then, you only need the main thread to loop and do simulation
3/ If you want 50 simulation seems to happen at the same time for user to watch, multithreading is also required:)
If you use threading, you won't know in what order the CPU is doing your tasks, and you could potentially be consuming a lot of thread scheduling resources. Better to use an NSOperationQueue and signal completion of each task using performSelectorOnMainThread. Decrementing a counter has already been mentioned, which may be useful for displaying a progress bar. But you could also maintain an array of 50 busy flags and clear them on completion, which might help debugging whether any particular task is slow or stuck if you mark completion with a time stamp.
Can any body explain me what is the difference among sleep() , usleep() & [NSThread sleepForTimeInterval:] ?
What is the best condition to use these methods ?
sleep(3) is a posix standard library method that attempts to suspend the calling thread for the amount of time specified in seconds. usleep(3) does the same, except it takes a time in microseconds instead. Both are actually implemented with the nanosleep(2) system call.
The last method does the same thing except that it is part of the Foundation framework rather than being a C library call. It takes an NSTimeInterval that represents the amount of time to be slept as a double indicating seconds and fractions of a second.
For all intents and purposes, they all do functionally the same thing, i.e., attempt to suspend the calling thread for some specified amount of time.
What is the best condition to use
these methods ?
Never
Or, really, pretty much almost assuredly never ever outside of the most unique of circumstances.
What are you trying to do?
On most OSs, sleep(0) and its variants can be used to improve efficiency in a polling situation to give other threads a chance to work until the thread scheduler decides to wake up the polling thread. It beats a full-on while loop. I haven't found much use for a non-zero timeout though, and apple in particular has done a pretty good job of building an event driven architecture that should eliminate the need for polling in most situations anyway.
-Example usage of sleep is in the following state:
In network simulation scenario, we usually have events that are executed event by event,using a scheduler. The scheduler executes events in orderly fashion.
When an event is finished executing, and the scheduler moves to the next event, the scheduler compares the next event execution time with the machine clock. If the next event is scheduled for a future time, the simulator sleeps until that realtime is reached and then executes the next event.
-From linux Man pages:
The usleep() function suspends execution of the calling thread for (at least) usec microseconds. The sleep may be lengthened slightly by any system activity or by the time spent processing the call or by the granularity of system timers.
while sleep is delaying the execution of a task(could be a thread or anything) for sometime .Refer to 1 and 2 for more details about the functions.
Say I have two NSTimers in my iPhone app: timer1 and timer2. timer1 calls function1 30 times per second and timer2 calls function2 30 times per second. Assume these two functions are reading and updating the same integer variables. Are there any "multi-threading" issues here? If not how does iPhone OS handle the execution of the two functions (in general)?
The core of any iPhone application (and some other platforms) is a run loop. Each thread may have a run loop, and the run loop on the main thread is set up for you. When there is something to do, like fire an NSTimer or draw the view hierarchy, the run loop performs those tasks. When there is nothing to do, the run loop is idle, allowing other things to process.
The run loop internals are thread aware so that nothing handled by the run loop has to be. All the NSTimer callbacks and view rendering happens on a single thread in a serial or linear flow.
For specific details, you can look up NSRunLoop or CFRunLoop.
As far as I'm aware, NSTimers use the run loop to achieve their 'asynchronosity'. If the timer is created using the scheduledTimerWith... method then it will be scheduled on the default (main) run loop and will be executed on the main thread.
I don't think any new threads are created for the timer (unless you do it explicitly, and assign the timer to that run loop).
So in the end, I believe your two timers shouldn't conflict with each other.
However, the documentation states that timers don't represent real time. The timer will fire on or after the scheduled time, but is not guaranteed to fire exactly at the scheduled time. Therefore if the fired method takes longer to execute than the interval of the timer, you may not see the method called as often as you'd expect.
With that said, is there any particular reason you're asking the question? Are you seeing undesired behaviour using this setup?