Skip to Main Content

Java Programming

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Java Multithreaded performance decrease, what am I doing wrong?(winXP)

807589Sep 26 2008 — edited Sep 27 2008
Greetings Everyone,

I have a question. I am experiencing some strange result in my Java application. I(we actually) made a Ray tracing program, which runs inside a Frame(awt) and for every pixel it uses a Ray class to determine the colour of the pixel.

As the program was originally single threaded I rewrote it to multi threaded by rewriting the render method like this:
( a quick description first to make it a bit more comprehensible)
There is one class named Tracer...which extends Frame and in its main it creates a new Tracer. Tracer contains a lot of public statics containing all the screen en scene info(objects, lights...), but also a static Tracer object which is the Tracer created inside the main, this access the non static methods...(not a very nice way of doing this...but for now it ended up like this...thus Tracer.mainFrame is actually the Tracer object created in the main and used to access non static methods...)
	public void render() {
		
		pixelBuffer = new int[ width*height ];
		imageSource = new MemoryImageSource( width, height, pixelBuffer, 0, width );
		imageSource.setAnimated( true );
		offscreenImage = Toolkit.getDefaultToolkit().createImage( imageSource );
		
		
		ToneMapper toneMapper = new ToneMapper( gamma );

		startTimeRend =  System.currentTimeMillis();
		
		for( int y=0; y<height; ++y ) {
			for( int x=0; x<width; ++x ) {
		
				int index = (height-y-1)*width + x;
				Vec3 color = tracePixel( x, y );
				pixelBuffer[ index ] = toneMapper.map( color.x, color.y, color.z );
				
			}
			if( (y&7) == 0 ) paint( getGraphics() );
		}
		//Visually it could still miss a bar...this is to display the full image:)
		paint( getGraphics()); 
		long time = System.currentTimeMillis() - startTimeRend;
		System.out.println( "Finished raytracing in " + time/1000.0f  + "s." );	
	}
To this: (startTimeRend is class float)
	public void render(int threads) {
		
		pixelBuffer = new int[ width*height ];
		imageSource = new MemoryImageSource( width, height, pixelBuffer, 0, width );
		imageSource.setAnimated( true );
		offscreenImage = Toolkit.getDefaultToolkit().createImage( imageSource );
		
		startTimeRend =  System.currentTimeMillis();
		
		int yParts = (int) (height /threads);
		threadsRunning = threads;
		for(int i=0;i<threads;i++){
			RenderThread rendT = new RenderThread(i*yParts,(i+1)*yParts);
			rendT.start();
		}
		
	}

public void renderV(int from, int to) {
		
		
		ToneMapper toneMapper = new ToneMapper( gamma );
		
		for(int y=from;y<to;y++){
			for( int x=0; x<width; ++x ) {
				
				int index = (height-y-1)*width + x;
				//while(index<0){index = (height-y-1)*width + x;}
				Vec3 color = tracePixel( x, y );
				pixelBuffer[ index ] = toneMapper.map( color.x, color.y, color.z );
				
				
			}
		}
		
		paint( getGraphics() );
		
		finishRender();
	}
public void finishRender(){
		threadsRunning--;
		if(threadsRunning<=0){
			paint( getGraphics()); 
			long time = System.currentTimeMillis() - startTimeRend;
			System.out.println( "Finished raytracing in " + time/1000.0f  + "s." );
			progThread.dispose();
		}
	}
And the thread class I use
class RenderThread extends Thread implements Runnable{


	int pixelYfrom = 0;
	int pixelYto = 0;
	
	RenderThread(int from, int to){
		if(from!=to){
			if(from<to){
				pixelYfrom = from;
				pixelYto = to;
			}else{
				pixelYfrom = from;
				pixelYto = to;
			}
		}
	}
	
	
	public void run() {
		Tracer.mainFrame.renderV(pixelYfrom, pixelYto);
		
	}
}
Where render(x) the x is the number of threads to use(obviously).

The strange thing is though. That even though both methods render almost identically and give the the the same result the single threaded render runs faster than the multi threaded render when using 4-8 threads. When using 2 threads it seems to be going slightly faster. I haven't tested 3 though. My question is why? When using 2 threads I get only 50% total usage(I have a Quad core running at 2.66Ghz) and with 4 threads I get around the 95% and with 8 threads about 75%(which is also strange, though I guess it might have something to do with more scheduling) So why are 2 threads faster than 4?(I guess 2 are bit better then the single threaded version, though I don't know its effects on a dual-core machine)

and is there a way to fix this? So that I can use the 95% of my pc and still get an adequate performance increase.(I wrote the code almost identically in C++ and there the thread increase would cause a performance increase(especially around the 4-5 threads), but it doesn't seem to work here.)

Thanks in advance

Edited by: NeoAngelus on Sep 26, 2008 11:00 AM extra info
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Oct 25 2008
Added on Sep 26 2008
12 comments
574 views