8

I was going through a Java tutorial where it was mentioned that actual multithreading doesn't happen in a machine having a single processor. It mentioned that OS allots a specified amount of time for the Java process and JVM thread scheduler picks up threads for running one thread at a time for a small amount of time.

I have a laptop which quadcore processor - it is possible to run a multi-threaded program faster programatically by running one thread in each core? The reason why I am asking this question is because the book mentioned that only a true multi processor system can do multiple things at the same time.

Makoto
  • 104,088
  • 27
  • 192
  • 230
Punter Vicky
  • 15,954
  • 56
  • 188
  • 315
  • 1
    Went ahead and added the multithreading tag to this - it's not just a Java-centric question. Hopefully you'll get some great answers. – Makoto Jan 30 '12 at 05:39
  • The article you read was probably from time before multi-core processors, so states taht only multi-processor computer can utilise it. – Hurda Jan 30 '12 at 09:56

4 Answers4

8

Even a single CPU can do "multiple things at the same time" in a loose sense, but they are not truly in parallel. You can start 100 threads to run on a single core and they will get time slices during which each of them can run a few instructions, thus creating the impression that they are all executing at the same time.

As I've said in another SO post: multithreading on dual core machine?

The term threads usually covers three abstraction layers:

  1. User threads are threads launched by applications and are mapped N:M to:
  2. Kernel threads, which are threads managed by the operating system, mapped N:M to:
  3. Hardware threads, which are the actual physical resources available.

Java threads are user threads. The 4 cores in your CPU count as hardware threads. Since the mapping is N:M across the layers, you can see that you can have several user threads mapped to a smaller number of hardware threads.

Now, having said this, there are generally two classes of thread activities, each with their own quirks:

  1. I/O threads: these threads spend most of their time waiting on read/write operations from a stream and are blocked in the meantime (they are not scheduled for execution until an event occurs to wake them up). There are light on the CPU and a lot of them can run concurrently even on a single core.
  2. Computational threads: these thread do a lot of number crunching and use the CPU to the maximum. Generally starting more than (2x the number of available cores) such threads is going to degrade performance, because the CPU has a limited number of functional units: ALUs, FPUs, etc.

The second class of threads above lets you really see the benefit or running a multithreaded java program on your quad-core CPU. Here is a simple example of a program that executes squaring of 1.000.000.000 numbers first sequentially and then in parallel using a thread pool with 4 threads:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class ThreadTask implements Runnable {

    private int total = 0;

    public ThreadTask(int total) {
        this.total = total;
    }

    @Override
    public void run() {
        int value = 0;
        for(int i = 0; i < total; i++) {
            value = i * i;
        }
    }       
}

public class Test {

    public static void main(String[] args) throws InterruptedException {

        int total = 1000000000;

        long start = System.currentTimeMillis();
        long value = 0;
        for(int i = 0; i < total; i++) {
            value = i * i;
        }       
        long stop = System.currentTimeMillis();

        System.out.println((stop - start) + " ms");

        ExecutorService exec = Executors.newFixedThreadPool(4);
        start = System.currentTimeMillis();
        for(int i = 0; i < 4; i++) {
            exec.submit(new ThreadTask(total / 4));
        }
        exec.shutdown();
        exec.awaitTermination(10, TimeUnit.SECONDS);
        stop = System.currentTimeMillis();

        System.out.println((stop - start) + " ms");     
    }
}

Feel free to adjust the value of total if it's running too fast. Now I'm working on a netbook with Intel Atom, so it not really fast.

Community
  • 1
  • 1
Tudor
  • 61,523
  • 12
  • 102
  • 142
2

Even with only one processor multiple threads can make your program faster it all depends on the work you're trying to speed up. For instance if your threads are waiting for IO. If it's purely computational then you'd probably want to limit your threads to your number of cores.

Measure it test it with experiments.

Tom
  • 43,583
  • 4
  • 41
  • 61
2

A multi-core processor can 'truly' parallelize the work in your application up to the number of cores you have. In your case, that would be 4 threads. Read more about multi-core vs multi-processor at Wikipedia. Having said that, you can realize performance benefits with a multi-threaded algorithm on a single core CPU, despite the fact that you only have one processor.

The improvement in performance gained by the use of a multi-core processor depends very much on the software algorithms used and their implementation. In particular, possible gains are limited by the fraction of the software that can be parallelized to run on multiple cores simultaneously; this effect is described by Amdahl's law. In the best case, so-called embarrassingly parallel problems may realize speedup factors near the number of cores, or even more if the problem is split up enough to fit within each core's cache(s), avoiding use of much slower main system memory. Most applications, however, are not accelerated so much unless programmers invest a prohibitive amount of effort in re-factoring the whole problem2. The parallelization of software is a significant ongoing topic of research.

Also see this StackOverflow question.

Community
  • 1
  • 1
Amir Afghani
  • 37,814
  • 16
  • 84
  • 124
1

I can confirm that, on my i3 laptop, algorithms that run in parallel go nearly twice as fast aspects a serial algorithm.

more context added below...

These are highly computational algorithms with no I/O. Basically, calculating statistics on N large arrays, where each array can be done independently. I find that using a thread pool of 2-4 threads all yields about the same speed increase - 2X. Going to 8 or more threads, things start slowing down slightly as you get more contention (and are using up more memory). On a processor with more cores these values would change.

user949300
  • 15,364
  • 7
  • 35
  • 66