Situations for multithreading [closed]
Are there any guidelines to know whether a particular program will benefit from multithreading?
In single threads, the CPU utilization is often low, which could be higher in 开发者_JS百科some cases if unrelated parts of a program are made into separate threads. Maybe when one thread is waiting for I/O, the other threads can utilize the CPU. But any things to look out for in a program to see whether it would benefit from multithreading?
Usually, multithreading is good when you can decompose a task in several independent subtask and you effectively have several processors to perform the task (optimization), or if you need to keep your system "interactive" (even if a blocking task, like reading from the network, is being performed, other threads can keep attenging user requests, for example).
And another reason is to simulate paralelism (even if you haven't got as many processors as threads) to execute several "tasks" simultaneously (even if not real optimization is achieved). That is what tipically Operating Systems do, they run several programs in paralell, even if they have to give to them little portions of time to execute alternatively.
To use multi-threading you must have independant tasks which can be performed concurrently. These need to be non-trival, ideally atleast 10 micro-seconds in length otherwise the overhead of using multiple threads could be higher than the advantage of using multiple threads.
If you process is IO bound, it can benefit from using multiple threads even if you have only one core. If your process is CPU bound you have to have free cores to improve performance.
The most improvement a CPU bound process can have is equal to the number of cores. i.e. if you have N cores it can go up to N times faster. This assumes you have atleast N independant tasks you can perform.
Often optimising the code can make your application go much faster that this without major changes.. The largerest improvement I have done by changing the code is 1000x better than the previous implementation. For this reason your first step should be to profile and anlyse your system to see if it can be improved. After that consider multi-threading your application.
Passing work to another thread is not trivial, esp if you are passing a small number of large tasks. Queues can handle high throughputs, but if you want to complete a task in the minimum amount of time latency matters.
This was run on a modest 2.3 GHz T4500. The amount of data passed is trivial and as you access more data between threads the longer it takes.
ExecutorService es = Executors.newCachedThreadPool();
for(int i=0;i<20;i++) {
Thread.sleep(10);
Future<Long> future = es.submit(new Callable<Long>() {
long start = System.nanoTime();
public Long call() throws Exception {
return start;
}
});
System.out.printf("Took %.1f us to submit/get%n",
(System.nanoTime() - future.get())/1e3);
}
es.shutdown();
prints
Took 61.1 us to submit/get
Took 45.1 us to submit/get
Took 49.1 us to submit/get
Took 37.9 us to submit/get
Took 58.5 us to submit/get
A program will in MOST cases benefit from multi threading nowadays, because of the nature of Muli-Core CPUs. A single thread can only work on one core at a time, while several threads can spread over multiple cores.
The more important question would be: When is it possible to multi thread? Which tasks can be parallelized? Often this is not possible and sometimes not even desired because it introduces a very hard to debug unpredictable element to your code: race conditions.
And yes, if your program is waiting a lot on I/O for example than your CPU is often idle in this time. If there is anything you can do with the CPU in the meantime, than it will increase performance naturally ;-). Even on single core.
Another update: Also keep in mind, that it is possible to overdo multi threading. If you have more threads than CPU cores running, than your scheduler will have to switch between those threads, which is some overhead. If your threads are not blocking (I/O or other things), than this overhead is just a waste of time.
Multithreading is normally often a good idea since you'd then be able to leverage the power of multiple cores. Modern CPUs often don't get faster cores but more cores, thus your application would benefit from that if it is multithreaded.
As already said, the hard task is to get multithreading right. In most cases you should design your application specifically for multithreading. If you have a single threaded application and want to speed that up, you might look for lengthy operations that might be split into multiple parts (look for loops where each iteration is indepent of the others, for example) .
However, keep in mind that multithreading imposes some overhead as well, thus the individual tasks need a certain miminal size in order to be effective.
Note the answers provided by the other posters, to which I would add a few:
1) Apps that must handle multiple operations that require timeouts and/or delays. Multiple threads can eliminate complex and difficult-to-debug state-machines, (a thread is effectively a state-machine run by the OS). The obvious example is multi-channel comms apps that need delays to implement specific protocols - sleep() is much easier to both implement, understand and debug than all the timers, callbacks etc. etc. than infest single-threaded apps that need this functionality. Running a separate thread for each channel allows such code to be written 'in-line'. Once you have got one channel working, 100 is no problem.
2) Apps that need API's that block. There are some API's, (well, on Windows anyway), that block and do not have an asynchronous alternative, esp. on older OS. Without a dedicated thread to call these, you will get stuck.
3) Apps where multiThreading the solution looks like it will be quicker, but provide just insufficient cost/performance benefit to make it worth while. Next year, things will be different.
4) Apps that are part of a large system and have a printed requirement spec heavier than ~ 100g, start thinking multiple threads.
5) If the app is trivial, not time-constrained and you have little/no threading experience, thread off part of it anyway, just for the fun, (?), of it. After a while, you will just know how to structure large, complex apps so that they will work reliably and are maintainable and expandable. 'I don't do multiple threads' does not go down well in an interview :)
Rgds, Martin
精彩评论