Multiple Threads, Multiple Cores

Hi,

I have a core 2 duo, which I assume means that there are two CPUs inside my machine, each running at 1.8 GHz… When my OpenGL Java program runs in a single thread (i.e. just a “normal” program–nothing fancy, everything comes from main()) does it just run on one core? Or does the Java Virtual Machine/Windows Vista cleverly farm out bits of code that are executed simultaneously on both processors in parallel and then magically stick the results back together so that resulting execution looks like it ran on a single processor? (In this case the fact that there are multiple cores is abstracted from the program)

OR…

Do I have to programatically spin off another thread outside of main() and explicitly tell that thread to go and run on another core? If this is the case, then is there some Java command/function that selects cores…or does the act of creating another thread give the JVM a chance to work farm it out to cores that it finds aren’t so busy? (In this case the program needs to be written to take advantage of multiple cores)

Questions, questions…

Thanks people!

/Mark

Since the VM uses several threads, the entire VM will use multiple cores. However, your application will ony use 1 core (unless your application is multithreaded).
As for OpenGL code, this is typically single threaded, and indeed the OpenGL driver is single threaded.

Single threaded applications will only run in a single core. When you have multiple threads the JVM decides where and when they will run, it may use the second core or it may run the thread in the same core. You don’t really have any control over that. But in general java will take as much of the system resources as it can get, so if your program has multiple threads that are both using a lot of CPU time it will probably use both cores.

By the way, this has many consequences to the code performances, and as a matter of fact, the ThreadStack will be treated differently on single- and multiple-core systems. For instance, Windows does get much more resources to synchronize on screen with Swing than a Mac OS X does. It’s my own experience about that, since I test my code both on ix86 arch and ppc arch. on the other side, single-threaded applications don’t provide the best effort on a single-core or non-HyperThreading (unlike ppc ARE obviously 2 logic-channels cpu’s) machine because system processor architectures do manage simple functions to be dispatched on both channels (if any available).
There’s a conclusion about that speciality on multi-threading, one application will get the best effort only if it launches as more threads the Stack can afford, because the more the code-logic looks like the processor(s) logic, the faster the system may compile and dispatch events to the core(s). It’s as easy to understand.
My own experiences proved that I got the best results when targeting my code structure to a multi-threaded style than focusing on single-threaded. Moreover, it looks like the Swing-Timers do not like much to coalesce their events as the actions become slower, and therefore I modified the most of my Timer-Action’s to instance a new Thread when required by sort of long processes. This is know as “coalesceing events”.

More concretely, most parts of my code are timed Events, e.g. be that function an usual send-notify a new value to a selected Object :


/** this is the action Thread to make coalesceing */ 
Thread myActionThreadRef;
function Object doActionOff() { // or whatever function you need
          int x = this.positionX;
          sendEventToObject(receiver, x);
          notifyEventToObject(receiver);
          return this.status;
}
javax.swing.Timer swingTimer = new javax.swing.Timer(10, new ActionListener() { public void actionPerformed(ActionEvent e){
          // here's the trick I mentioned, t is instanciated to free the Swing Timer faster than usual, 
          //which has the advantage to manually "coalesce" as Swing does it.
          if(myActionThreadRef instanceof Thread)
             if(myActionThreadRef.isAlive())
                   return; // I don't launch the thread because there's the previous one unterminated 
           Thread t = myActionThreadRef = new Thread(new Runnable() { public void run() {
                    Object status = doActionOff();
                    // I never let my objects states un-logged... So here I stick to the rule.
                    System.out.println(status);
           }});
           // maybe set priority to max
           t.setMaxPriority(Thread.MAX_PRIORITY);
           t.start();
}});

This has speeded up to twice the application, something I’m still bringing up for the moment. ::slight_smile:
Multi-Threading has many advantages but requires to be experienced with synchronization patterns, as a must-have. :smiley:

… and how to avoid them :wink:

Moderation is the key; it’s good to know how multi-core processors can benefit your program, but it’s also good to know when they will not. If you expand the concept of multiple processors to a size of [say] 150, then you have to consider then how they will communicate with each other to perform the task. What you find happens is that your code becomes less optimal as you increase the number of processors due to inter process communication.

There are some processing tasks which can easily be divided across processors and have speed gains in closer proportion to the full potential of the processor, but most tasks are not.