4

In the program I'm working on, I want the user to be able to input the number of processing threads that their processor has so that the program can divide the workload (it's doing general calculations) between the number of threads the user's computer has.

Alternatively, is there a way that you can get the program to detect the system configuration to get the number of threads without asking the user? This would be preferable, but I don't know if there is a way to do this.

Here is the only thing I've been able to think of. I know that it is completely incorrect, and that you can't name a thread that way, but I'm a beginner (still in high school), and I just wanted to include something to show that I'm trying.

for(int i = 0; i < threads; i++) {

    Thread thread(i) = new Thread(){
        public void run() {
            double endNum = 0;

            for(double numberRun = 0; numberRun <= calcs/threads; numberRun++){
                endNum += (num * 999999999);
            }

            System.out.println("Thread " + i + " complete! The numerical result of the calculation is " + endNum);
        }
    };
}

Everyone who isn't sure what I'm saying, I'm trying to create the number of threads that the computer has, aka the number of cores, or, if it's using Intel's HyperThreading, twice the number of cores. You can have more threads than the system is capable of executing at once, but I'm trying to do the most efficient thing and divide the total number of calculations into the number of threads that the system is capable of executing simultaneously. I do not know how to let the user define the number of threads and then create that number of threads (or let the program determine the number of threads the system has and then create that number).

skaffman
  • 398,947
  • 96
  • 818
  • 769
user1137371
  • 41
  • 1
  • 4
  • 6
    Did you check this: http://stackoverflow.com/questions/1980832/java-how-to-scale-threads-according-to-cpu-cores – home Jan 08 '12 at 18:33
  • It wouldn't make sense unless you also pinned them to a core/HT but even then you should know that your threads are not going to be alone in a modern multi tasking OS so in most cases you are much better off letting the operating system's scheduler decide what to run and when. It will do a pretty good job whereas you have no way of knowing what the other threads in the system are doing and risk getting worse performance if you was able to pin one of your threads to a core being busy with something else. – Fredrik Jan 08 '12 at 18:56
  • @Fredrik - for CPU intensive tasks (and assuming this is the only one or the most prevalent one on the machine), you generally don't want to run more threads than you have CPUs, otherwise you're just creating contention. But you don't want to undercut the number of CPUs either, because you'd not be using all of them. nCPUIntensiveThreads == nProcessors is actually a pretty fair target. – James Jan 08 '12 at 19:06
  • @james you are correct saing that you probably don't want more threads than cores (unless the alternative is to run the extra job directly afterwards anyway) but aiming at an equal amount could prove just as bad unless you are alone on the system or have control over the scheduler. Starving out other threads could easily damage your overall performance in a managed world unless you are very aware of what your threads are depending on. For a newbe, optimizations like this will most likely hurt performance. – Fredrik Jan 08 '12 at 19:27
  • I would suggest going with an executor service with nuber of cores -1 as the pool size. – Fredrik Jan 08 '12 at 19:29
  • @Fredrik - for a newbe, everything will hurt performance :) Like running cores - 1 on a single core machine (yes, they do still exist, I swear) - but seriously, on a quad core machine, you're losing 25% of your potential power at cores - 1. And if you overload other things on the machine, the obvious thing is to reduce the work you're doing at once, which would lead you to dropping to cores -1 anyhow. – James Jan 08 '12 at 19:35
  • @james I do pretty CPU intensive things for a living and even if you are right in theory and especially if you do C or C++ there are too much going on in the JVM alone but even in yhe OS to be completely true (and of course i wasn't suggesting setting the pool size to 0 :-) ).There are edge cases where it will work well, typically when you have nothing but primitive math and each part is rather short lived but in most other cases you will either risk being preempted or be scheduled on the same thread as one of your other threads anyway (unless you set affinity but that's even harder) – Fredrik Jan 08 '12 at 19:51
  • But it is probably a matter of perspective and varying milage as there is usually not a single correct answer to issues like optimization and scaling. – Fredrik Jan 08 '12 at 19:53

7 Answers7

4

You can find out how many processors are available to the JVM like this:

Runtime.getRuntime().availableProcessors()

The optimal number of threads for splitting a pure numeric calculation over is probably one per processor. If any of those threads have to occasionally block on IO, it might be more.

Russell Zahniser
  • 16,188
  • 39
  • 30
  • But then how do I create the number of threads that the user's computer has? This is meant to be able to run on a lot of different system configurations, and the program is supposed to automatically create the right number of threads. – user1137371 Jan 08 '12 at 19:00
  • @user11373731 - I think you're mixing the words threads and processors in your comments. The above command posted tells you the number of processors available - that is the number of threads you want, as well, in general. – James Jan 08 '12 at 19:07
  • @James - I know that the number of processors is also the number of threads you want, but I do not know how to get the program to execute the calculations over that number of threads once it determines how many to use based off of the result from that code snippet. – user1137371 Jan 08 '12 at 19:14
  • @user: Check out James' answer below. – Russell Zahniser Jan 08 '12 at 19:16
  • @user1137371 - if you're asking how to run it, see below. If you're asking how to break up the calculation into separate tasks, you'd have to provide more information about what you're calculating, as it's fairly task specific (and thus the hard part!) – James Jan 08 '12 at 19:36
3
class Task implements Runnable {
  Task(/** Whatever you need to identify the subset of tasks to run goes here*/) {

  }

  public void run() {
    // do the calcs
  }
}

int nProcs = Runtime.getRuntime().getAvailableProcessors();

Task[] tasks = new Task[nProcs];
for (int i = 0; i < nProcs; i++) {
   tasks[i] = new Task(/** Whatever parameters for this batch*/);
   new Thread(tasks[i]).start(); 
   // Alternatively, use Executors.newFixedThreadPool() to get a service above, and submit the runnable there, getting a future for the result, something like this:
   Future f = executor.submit(task[i]);
}

}

James
  • 8,512
  • 1
  • 26
  • 28
  • James, is there a chance i could email you about this? I have a couple questions and some code that would be somewhat difficult to talk about here. If you have time, please email me at numa.robertson@gmail.com – user1137371 Jan 08 '12 at 20:31
2

If you're going to be executing a bunch of different distinct tasks – as opposed to trying to split one big task into multiple smaller tasks running in parallel, you might want to use an Executor:

Executor e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// run a single task
e.execute(new Runnable() {
    public void run() {
        // do stuff here
    }
});

As others have pointed out, the optimal size of your thread pool depends on various factors like how much IO the tasks do, but the number of available cores should be a sensible default.

millimoose
  • 39,073
  • 9
  • 82
  • 134
  • I am trying to split one big task (repeatedly doing an equation) between all available processing threads. – user1137371 Jan 08 '12 at 19:02
  • @user1137371 Then it doesn't really matter if you use threads directly or use an executor, although I still like the latter because of Futures. In the body of the Runnable, you can use the method body from your question, and the value of `threads` will be `Runtime.getRuntime().availableProcessors()` (or whatever you deem appropriate.) – millimoose Jan 08 '12 at 19:09
1

what i like to use is the ExecutorService executor = Executors.newFixedSizeThreadPool(int numberOfThreads);

and then have the executor.execute(myRunnable) your runnables :) In this approach, you're not responsible for creating the threads, and you have the guarantee you're not creating unnecessary threads.

but as to how you would figure out how many threads you should use, that's up to you to research.

vlad-ardelean
  • 7,480
  • 15
  • 80
  • 124
1

It seems to me that what you are looking for is also a mapping strategy of tasks to threads. For example, a loop such as:

for(int i = 0; i < LARGE_NUMBER; i++) {
    f(i);
}

can be converted to a parallel version as:

class Task implements Runnable {
    private int i;

    public Task(int i) {
       this.i = i;
    }       

    public void run() {
       f(i);
    }
}

then replace the initial for loop with:

ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < LARGE_NUMBER; i++) {
    exec.submit(new Task(i));
}

exec.awaitTermination(1000, TimeUnit.HOURS); // wait for all tasks to finish

The ExecutorService will take care of using a number of threads adequate with respect to the available processors as well as recycling the threads such that the tasks are executed on-demand.

Tudor
  • 61,523
  • 12
  • 102
  • 142
0

Numer of threads doesn't depends of processor. If you're using single processor, then your programm will jump from one thread to another.

So, there nothing "incorrect" in your method (of course, if you will use it properly).

Dmitry Zaytsev
  • 23,650
  • 14
  • 92
  • 146
  • Optimal number of threads certainly -does- depend on number of processors, if you're going for something CPU bound and performance critical. – James Jan 08 '12 at 18:55
0

I think you're asking about the MAXIMUM number of threads a system can have??

As discussed here, there's no maximum number of threads a system can have (as Java programs run inside the Java Virtual Machine, the limit you're going to have is that of the Java Virtual Machine - JVM). The limit is on the amount of resources you can allocate to your threads.

If you're asking about how many threads are currently running (which may have been started by any external program or inside the JVM), then you probably can find that out, but I think it won't be of any use for your case as the threads you start are not related in any way to other threads running in the system!

Community
  • 1
  • 1
Renato
  • 12,940
  • 3
  • 54
  • 85
  • In practice, you can almost definitely allocate more threads than you can reasonably use. After more than a few thousand, you start spending a fairly significant amount of CPU just switching between them. – James Jan 08 '12 at 18:56