Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 10 of 10

Thread: Many thread benchmark help

  1. #1
    Member
    Join Date
    Feb 2012
    Posts
    173
    Thanks
    6
    Thanked 10 Times in 10 Posts

    Default Many thread benchmark help

    I'm building a simple benchmark program that proves the primality the largest 64-bit unsigned prime number. So far, I can set up the threads and they all run correctly, but in an effort to increase the efficiency in which the threads are executed, I want to start all the threads at once. I don't know how to do this, or if it is even possible. Currently I have it loop through an array list of the threads starting each one individually. The number of threads created is your free memory divided by five megabytes (5 * Math.pow(2,10)). Also, am I waiting for termination the right way?

    Execution class:

    package benchmark;
     
    import java.util.ArrayList;
     
    import javax.swing.JOptionPane;
     
    public class Run {
     
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
     
    		long lim = (long)4294967296.0;//upper limit of loop
     
    		JOptionPane.showMessageDialog(null, "Welcome to the 64-bit prime benchmark. It measures how efficiently your machine can run through the algorithm.");
     
    		long threads = (Runtime.getRuntime().freeMemory())/(5 * (long)(Math.pow(2, 10)));//calculates the number of threads to use.
     
    		JOptionPane.showMessageDialog(null, "It will run using " + threads + " threads.\n\nPress OK to build the threads.");
     
    		ArrayList<Thread> th = new ArrayList<Thread>();//arraylist of threads
    		long  inc = lim/threads, s = 2;
    		for(long i = 0; i < threads; i++)
    		{
    			th.add(new Algorithm(s,inc+s));//creates each thread and adds it to the array list
    		}
     
     
     
    		JOptionPane.showMessageDialog(null, "Threads built. \n\nPress OK to run benchmark.");
    		long start = System.currentTimeMillis();//times the amount of time it takes
    		for(int i = 0; i < threads; i++)
    		{
    			th.get(i).start();//starts each thread
    		}
     
    		while(th.get(th.size()-1).isAlive())
    		{}//waits for the last thread in the list to terminate
     
    		long end = System.currentTimeMillis();//end of the timer
     
                 //prints some stats
    		JOptionPane.showMessageDialog(null,"Statistics:\n" +
    				"Time: " + (end - start) + " ms.\n" +
    				"Total iterations: " + lim/2 + "\n" +
    				"Iterations per second: " + ((lim/2)/(end-start))*1000+"\n" +
    				"Number of threads: "+ th.size());
     
    		System.exit(1);
    	}
    }

    Algorithm():

    package benchmark;
     
    import org.jscience.mathematics.number.LargeInteger;
     
     
    public class Algorithm extends Thread{
     
    	/**
    	 * @param args
    	 */
     
    	private LargeInteger val = LargeInteger.valueOf("18446744073709551557");//number being factored
    	private long start, end, increment = 2;//runtime variables that specify where to start, stop, and the increment for each number
     
    	/**
    	 * @param start - value to start at
    	 * @param end - value to end at
    	 */
    	public Algorithm(long start, long end)
    	{
    		this.start =start;
    		this.end = end;
    	}
     
    	public synchronized void run()
    	{
    		//System.out.println("Thread: " + threadNum + " starting. Thread ID: " + getId());
     
    		LargeInteger lim = LargeInteger.valueOf(end);//LargeInteger containing the end value
     
    		for(LargeInteger i = LargeInteger.valueOf(start); lim.isGreaterThan(i); i.plus(increment))//loop for primality check
    		{
    			if(val.mod(i).equals(0))//checks for accuracy of the thread
    			{
    				throw new RuntimeException("Inaccurate Process.");//throughs an exception if an error is made showing the value not prime.
    			}
     
    		}
    	}
    }

    I will attach the JScience library that I use here.
    Attached Files Attached Files


  2. #2
    Super Moderator curmudgeon's Avatar
    Join Date
    Aug 2012
    Posts
    1,130
    My Mood
    Cynical
    Thanks
    64
    Thanked 140 Times in 135 Posts

    Default Re: Many thread benchmark help

    Quote Originally Posted by aesguitar View Post
    ...but in an effort to increase the efficiency in which the threads are executed, I want to start all the threads at once. ...
    Why do you think that this will increase efficiency?

    Why do you feel that you're not starting them as close together in time as is possible?

  3. #3
    Member
    Join Date
    Feb 2012
    Posts
    173
    Thanks
    6
    Thanked 10 Times in 10 Posts

    Default Re: Many thread benchmark help

    Quote Originally Posted by curmudgeon View Post
    Why do you think that this will increase efficiency?

    Why do you feel that you're not starting them as close together in time as is possible?
    The thing is, I don't know. I was simply wondering if there was maybe an easier or faster way to do it, I don't have anything to compare it to as I'm not very good with multi-threading yet. Also, is the way I'm checking for full termination the right way to do it? Is there a better way perhaps?

  4. #4
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,042
    Thanks
    63
    Thanked 2,708 Times in 2,658 Posts

    Default Re: Many thread benchmark help

    How many different processors does the computer you are executing the program on have?
    Having one thread per processor will allow the threads to execute in parallel. Otherwise there is a chance that extra threads will lengthen the time taken to run the program due to OS overhead swapping between threads.
    If you don't understand my answer, don't ignore it, ask a question.

  5. The Following User Says Thank You to Norm For This Useful Post:

    aesguitar (December 20th, 2012)

  6. #5
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Many thread benchmark help

    How you're starting threads is just fine.

    I don't think you're waiting for threads to end correctly. For one, the last thread started isn't guaranteed to be the last one to finish execution. Secondly, you're consuming a lot of resources in your main thread waiting for the other threads to finish. This will drastically reduce your performance.

    A better way to wait for the thread to end is to use the join method. This consumes very little resources, and is guaranteed to wait for all threads to finish under normal circumstances.

    for(Thread t: th)
    {
        t.join();
    }

    Also, I noticed you're starting a rather large number of threads. More threads != better performance. Usually the ideal number of threads is around the number of physical cores your CPU has. There are ways to schedule tasks with a small number of worker threads to get better throughput and less memory. Do a search for Java thread pools.

  7. #6
    Member
    Join Date
    Feb 2012
    Posts
    173
    Thanks
    6
    Thanked 10 Times in 10 Posts

    Default Re: Many thread benchmark help

    I have a dual core i5 @ 2.4 GHz with hyperthreading giving 4 logical cores. I have it creating threads based on the amount of free RAM. When it runs, it uses 800,000 MB and around 90% of my processor. Should I only have like 1 or 2 threads per physical processor?

  8. #7
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,320
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: Many thread benchmark help

    The number of threads created is your free memory divided by five megabytes (5 * Math.pow(2,10))
    Think about this statement for a moment. A thread is run on a processor...each thread must 'coordinate' access to a processor to be able to run the code it contains. Imagine for the sake of argument you have 8 processors and a good amount of free memory - this means you could quite possibly be launching thousands of threads - each competing for your sole 8 processors. And remember, there is also the thread which spawns them - in the example above the main thread - which is also competing for its own processor time. In other words, spawning so many threads actually decreases performance. If you wish to push your computer, create a reasonable number of threads based upon the number of processors, not the amount of free memory - and don't forget the threads your program inherently owns but you don't directly create (for instance, the main thread)

  9. The Following User Says Thank You to copeg For This Useful Post:

    aesguitar (December 20th, 2012)

  10. #8
    Member
    Join Date
    Feb 2012
    Posts
    173
    Thanks
    6
    Thanked 10 Times in 10 Posts

    Default Re: Many thread benchmark help

    Did I do this correctly?

    for(Thread t: th)
    		{
    			t.start();
    		}
     
    		for(Thread t : th)
    		{
    			try {
    				t.join();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}

    I am also starting threads based on the number of processors now.

    long threads = (Runtime.getRuntime().availableProcessors()*4);

  11. #9
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Many thread benchmark help

    Yes, that looks much better.

  12. The Following User Says Thank You to helloworld922 For This Useful Post:

    aesguitar (December 20th, 2012)

  13. #10
    Member
    Join Date
    Feb 2012
    Posts
    173
    Thanks
    6
    Thanked 10 Times in 10 Posts

    Default Re: Many thread benchmark help

    Thank you all. It runs beautifully... I think...

    Final code:

    package benchmark;
     
    import java.util.ArrayList;
     
    import javax.swing.JOptionPane;
     
    public class Run {
     
    	public static long score(long time, long ipers, long threads)
    	{
    		return (ipers/time)*threads;
    	}
     
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
     
    		long lim = (long)4294967295.0;//upper limit of loop
     
    		JOptionPane.showMessageDialog(null, "Welcome to the 64-bit prime benchmark. It measures how efficiently your machine can run through the algorithm.");
     
    		long threads = Runtime.getRuntime().availableProcessors()*2;//calculates the number of threads to use.
     
    		JOptionPane.showMessageDialog(null, "It will run using " + threads + " threads.\n\nPress OK to build the threads.");
     
    		long tStart = System.currentTimeMillis();
     
    		ArrayList<Thread> th = new ArrayList<Thread>();//arraylist of threads
    		long  inc = lim/threads, s = 2;
    		for(long i = 0; i < threads; i++)
    		{
    			th.add(new Algorithm(s,inc+s));//creates each thread and adds it to the array list
    		}
     
    		long tEnd = System.currentTimeMillis();
     
    		JOptionPane.showMessageDialog(null, "Threads built.\nTime: " + (tEnd-tStart) + " ms\n\nPress OK to run benchmark.");
     
    		long start = System.currentTimeMillis();//times the amount of time it takes
    		for(Thread t: th)
    		{
    			t.start();
    		}
     
    		for(Thread t : th)
    		{
    			try {
    				t.join();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
     
    		long end = System.currentTimeMillis();//end of the timer
     
    		JOptionPane.showMessageDialog(null,"Statistics:\n" +
    				"Time: " + (double)(end - start)/1000.0 + " ms.\n" +
    				"Total iterations: " + lim/2 + "\n" +
    				"Iterations per second: " + ((lim/2)/(end-start))*1000+"\n" +
    				"Number of threads: "+ th.size() +"\n" +
    						"Score (higher=better): " + score(end-start,((lim/2)/(end-start))*1000, threads));//prints some stats
     
    		System.out.println("Statistics:\n" +
    				"Time: " + (double)(end - start)/1000.0 + " ms.\n" +
    				"Total iterations: " + lim/2 + "\n" +
    				"Iterations per second: " + ((lim/2)/(end-start))*1000+"\n" +
    				"Number of threads: "+ th.size() +"\n" +
    						"Score (higher=better): " + score(end-start,((lim/2)/(end-start))*1000, threads));
     
    		System.exit(1);
     
     
     
     
    	}
    }

    Algorithm:

    package benchmark;
     
    import org.jscience.mathematics.number.LargeInteger;
     
     
    public class Algorithm extends Thread{
     
    	/**
    	 * @param args
    	 */
     
    	private LargeInteger val = LargeInteger.valueOf("18446744073709551557");//number being factored
    	private long start, end, increment = 2;//runtime variables that specify where to start, stop, and the increment for each number
     
    	/**
    	 * @param start - value to start at
    	 * @param end - value to end at
    	 */
    	public Algorithm(long start, long end)
    	{
    		this.start =start;
    		this.end = end;
    	}
     
    	public void run()
    	{
    		//System.out.println("Thread: " + threadNum + " starting. Thread ID: " + getId());
     
    		LargeInteger lim = LargeInteger.valueOf(end);//LargeInteger containing the end value
     
    		for(LargeInteger i = LargeInteger.valueOf(start); lim.isGreaterThan(i); i = i.plus(increment))//loop for primality check
    		{
    			if(val.mod(i).equals(0))//checks for accuracy of the thread
    			{
    				throw new RuntimeException("Inaccurate Process.");//throughs an exception if an error is made showing the value not prime.
    			}
     
    		}
    	}
    }

    The LargeInteger class was posted earlier in the thread.
    Zip file containing the compiled program:
    Attached Files Attached Files

Similar Threads

  1. Replies: 2
    Last Post: August 30th, 2012, 09:45 AM
  2. Replies: 4
    Last Post: June 15th, 2012, 01:50 PM
  3. My First thread
    By shyandeep chatterjee in forum Member Introductions
    Replies: 0
    Last Post: April 18th, 2012, 05:06 AM
  4. What is this thread for exactly?
    By javapenguin in forum Computer Support
    Replies: 2
    Last Post: July 2nd, 2011, 10:37 AM
  5. Thread runs only once and not again
    By enflation in forum Threads
    Replies: 3
    Last Post: June 9th, 2010, 10:51 AM