Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Community » U++ community news and announcements » Painter refactored/optimized
Re: Painter refactored/optimized [message #50534 is a reply to message #50532] Tue, 13 November 2018 11:37 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Probably my bug.

Can you try to place Begin/End around DoPaint?

Mirek
Re: Painter refactored/optimized [message #50535 is a reply to message #50534] Tue, 13 November 2018 11:52 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
Yes. Begin()/End() around DoPaint(); equally fixes the issue with PainterExamples. But I think it would be nice to have a clean table after BufferPainter::Create()... Of course, I understand that each re-initialized variable increases the cost towards full constructor/destructor pair.

Best regards,

Tom
Re: Painter refactored/optimized [message #50536 is a reply to message #50535] Tue, 13 November 2018 11:55 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Sure, I agree, I justed wanted hints about the problem...
Re: Painter refactored/optimized [message #50537 is a reply to message #50536] Tue, 13 November 2018 12:22 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Please test (trunk).
Re: Painter refactored/optimized [message #50538 is a reply to message #50537] Tue, 13 November 2018 12:50 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
The issue is still there in SVN 12531 if you do my above changes to PainterExamples. (Obviously, adding Begin/End will still remove the issue.)

I can't figure out what exactly you changed in Create though. Or am I working on a completely wrong SVN version?

Best regards,

Tom
Re: Painter refactored/optimized [message #50539 is a reply to message #50538] Tue, 13 November 2018 13:54 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
rev 12531:

void BufferPainter::Create(ImageBuffer& ib, int mode_)
{
	ip = &ib;

	if(mode_ != mode || (Size)size != ib.GetSize()) {
		mode = mode_;

		rasterizer.Create(ib.GetWidth(), ib.GetHeight(), mode == MODE_SUBPIXEL);
		paths.Alloc(BATCH_SIZE);
		path_info = paths;

		ClearPath();

		render_cx = ib.GetWidth();
		if(mode == MODE_SUBPIXEL) {
			render_cx *= 3;
			subpixel.Alloc(render_cx + 30);
		}
		size = ib.GetSize();
	}

	Attr& a = attr;
	a.cap = LINECAP_BUTT;
	a.join = LINEJOIN_MITER;
	a.miter_limit = 4;
	a.evenodd = false;
	a.hasclip = false;
	a.cliplevel = 0;
	a.opacity = 1;
	a.dash = NULL;
	a.mask = false;
	a.invert = false;
	a.mtx_serial = 0;

	gradientn = Null;

	jobcount = fillcount = 0;
	cojob.Clear();
	cofill.Clear();

	attrstack.Clear();
	clip.Clear();
	mask.Clear();
	onpathstack.Clear();
	pathlenstack.Clear();
	onpath.Clear();

	preclip_mtx_serial = -1;
	path_index = 0;
}
Re: Painter refactored/optimized [message #50540 is a reply to message #50539] Tue, 13 November 2018 14:06 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
OK, the file was correctly updated. (Reverting my changes simultaneously slightly misguided me to believe otherwise.)

Anyway the problem is still there: The transformation matrix does not get reset to identity in Create.

Best regards,

Tom
Re: Painter refactored/optimized [message #50541 is a reply to message #50540] Tue, 13 November 2018 16:23 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Tom1 wrote on Tue, 13 November 2018 14:06
OK, the file was correctly updated. (Reverting my changes simultaneously slightly misguided me to believe otherwise.)

Anyway the problem is still there: The transformation matrix does not get reset to identity in Create.

Best regards,

Tom


What now?


void BufferPainter::Create(ImageBuffer& ib, int mode_)
{
	ip = &ib;
	
	if(mode_ != mode || (Size)size != ib.GetSize()) {
		mode = mode_;
	
		rasterizer.Create(ib.GetWidth(), ib.GetHeight(), mode == MODE_SUBPIXEL);
	
		render_cx = ib.GetWidth();
		if(mode == MODE_SUBPIXEL) {
			render_cx *= 3;
			subpixel.Alloc(render_cx + 30);
		}
		size = ib.GetSize();
	}

	if(!paths)
		paths.Alloc(BATCH_SIZE);

	path_info = paths;

	ClearPath();

	Attr& a = attr;
	a.cap = LINECAP_BUTT;
	a.join = LINEJOIN_MITER;
	a.miter_limit = 4;
	a.evenodd = false;
	a.hasclip = false;
	a.cliplevel = 0;
	a.opacity = 1;
	a.dash = NULL;
	a.mask = false;
	a.invert = false;
	a.mtx_serial = 0;
	
	gradientn = Null;
	
	jobcount = fillcount = 0;
	cojob.Clear();
	cofill.Clear();

	attrstack.Clear();
	clip.Clear();
	mask.Clear();
	onpathstack.Clear();
	pathlenstack.Clear();
	onpath.Clear();

	preclip_mtx_serial = -1;
	path_index = 0;
}
Re: Painter refactored/optimized [message #50542 is a reply to message #50541] Tue, 13 November 2018 17:23 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
Hi,

EDIT: Sorry, I did not pick up the changes yet. Please stand by. I will test these latest changes in the morning at the office.

Best regards,

Tom

[Updated on: Tue, 13 November 2018 18:29]

Report message to a moderator

Re: Painter refactored/optimized [message #50546 is a reply to message #50542] Wed, 14 November 2018 10:57 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
Hi Mirek,

As of r12533 Create now works as expected Smile

However, there seems to be a severe performance issue with MT. In some cases MT can be three times slower than MT before this optimization round. E.g. a vector map rendering in 20 ms with previous MT and in 40 ms with ST now takes 60 ms with new MT.

This is somehow related to changing transformations (of course within Begin/End pairs) which is now extremely expensive, especially when using MT.

Thanks and best regards,

Tom

EDIT: I created a transformation intensive view that shows a matrix of just 90 symbols. Each of the symbols are drawn with strokes and fills using a different translation for each within a Begin/End pair. Rendering of this same view takes only 2.2 ms with ST but a whopping 45 ms with MT! Using PreClip or not does not have any observable effect on the result.

[Updated on: Wed, 14 November 2018 11:37]

Report message to a moderator

Re: Painter refactored/optimized [message #50547 is a reply to message #50546] Wed, 14 November 2018 13:17 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Well, thats disappointing.

I really would like to have some example so I can optimize for this case.

Mirek
Re: Painter refactored/optimized [message #50548 is a reply to message #50547] Wed, 14 November 2018 13:39 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
Hi,

You can test with PainterExamples by enabling MT and running Benchmark with OnPath and OnTextPath examples.

Best regards,

Tom

EDIT: 'Pythagoras Tree Image' example portrays this slowdown too. Every other PainterExamples example running MT is on par or faster compared to ST. With my 4C8T Intel Core i7 the best MT gain is about 4x compared to ST. This is common with images and fills. Narrow geometries do not gain so much boost from MT landing at 1x-2x speed improvement.

[Updated on: Wed, 14 November 2018 14:03]

Report message to a moderator

Re: Painter refactored/optimized [message #50549 is a reply to message #50548] Wed, 14 November 2018 14:38 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Tom1 wrote on Wed, 14 November 2018 13:39
Hi,

You can test with PainterExamples by enabling MT and running Benchmark with OnPath and OnTextPath examples.

Best regards,

Tom

EDIT: 'Pythagoras Tree Image' example portrays this slowdown too. Every other PainterExamples example running MT is on par or faster compared to ST. With my 4C8T Intel Core i7 the best MT gain is about 4x compared to ST. This is common with images and fills. Narrow geometries do not gain so much boost from MT landing at 1x-2x speed improvement.


I have found that BeginOnPath was conservatively flushing rendering pipeline for no good reason, so that is now optimized out. TextOnPath is still slower if you fill the letters, that will have to wait till next batch of optimization I am afraid.

In fact, what is slow is alternating solid color / non-solid color fills - that is the case for both Pythagoras Tree Image and TextOnPath... Will have to think if there is anything I can do there...

[Updated on: Wed, 14 November 2018 14:40]

Report message to a moderator

Re: Painter refactored/optimized [message #50550 is a reply to message #50549] Wed, 14 November 2018 14:39 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
(P.S. that OnPath optimization is commited, I would be glad if you test it)
Re: Painter refactored/optimized [message #50551 is a reply to message #50550] Wed, 14 November 2018 14:56 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
Hi,

Absolutely! I'm extremely motivated to help you squeeze every single extra millisecond out of the rendering times in Painter!

OnPath show now 1.4x improvement over ST and OnTextPath about 2.3x improvement... And these were over ST not over previous MT where improvement is 5x that. Well done Mirek!

A question --- removed ---

Best regards,

Tom

EDIT: Removing question. Something else is now slowing down my code. It may be related to translations (Xform2D).

[Updated on: Wed, 14 November 2018 15:07]

Report message to a moderator

Re: Painter refactored/optimized [message #50552 is a reply to message #50551] Wed, 14 November 2018 15:19 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Tom1 wrote on Wed, 14 November 2018 14:56
Hi,

Absolutely! I'm extremely motivated to help you squeeze every single extra millisecond out of the rendering times in Painter!

OnPath show now 1.4x improvement over ST and OnTextPath about 2.3x improvement... And these were over ST not over previous MT where improvement is 5x that. Well done Mirek!

A question --- removed ---

Best regards,

Tom

EDIT: Removing question. Something else is now slowing down my code. It may be related to translations (Xform2D).


Well, what is definitely slow now if you are mixing solid fills and gradient or image fills. Can that be the cause?
Re: Painter refactored/optimized [message #50553 is a reply to message #50552] Wed, 14 November 2018 15:55 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
Hi,

My translated symbols are simply solid black over white background. The ST vs. MT speed ratio is about 15..20x in favor of ST. They were about equally fast when compiled against r.11960.

I need to find a pattern here. There is no clear Begin/End dependency as far as I can see. I'm trying to narrow down the code to find a test case.

Best regards,

Tom
Re: Painter refactored/optimized [message #50554 is a reply to message #50553] Wed, 14 November 2018 17:57 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Screenshot / piece of code would be helpful (can be PM).
Re: Painter refactored/optimized [message #50557 is a reply to message #50554] Thu, 15 November 2018 10:14 Go to previous messageGo to next message
Tom1
Messages: 1212
Registered: March 2007
Senior Contributor
Hi,

I finally figured out a way to share this test case. I send you code and a Serialized Painting to test. (Actually, this can be quite handy for any Painter performance issue testing in general.) Here's the code:

#include <CtrlLib/CtrlLib.h>
#include <Painter/Painter.h>

using namespace Upp;

class PainterBench : public TopWindow {
public:
	Painting p;
	FileSel fs;
	
	void Open(){
		if(fs.ExecuteOpen("Select a painting to view")){
			p.Clear();
			p.Serialize(FileIn(fs.Get()));
		}
	}
	virtual bool Key(dword key, int count){
		switch(key){
			case K_CTRL_O:
				Open();
				return true;
		}
		return false;
	}
	
	typedef PainterBench CLASSNAME;

	PainterBench(){
		Sizeable();
	}
		
	virtual void Paint(Draw &draw){
		int64 STtiming=0;
		int64 MTtiming=0;
		
		ImageBuffer ib(GetSize());
		{
			BufferPainter bpainter(ib);
			bpainter.Co(true);
			bpainter.PreClipDashed();
			bpainter.Clear(White());
			bpainter.EvenOdd();
			
			int64 t0=usecs();
			bpainter.Paint(p);
			int64 t1=usecs();
			MTtiming=t1-t0;
			
		}
		{
			BufferPainter bpainter(ib);
			bpainter.Co(false);
			bpainter.PreClipDashed();
			bpainter.Clear(White());
			bpainter.EvenOdd();
			
			int64 t0=usecs();
			bpainter.Paint(p);
			int64 t1=usecs();
			STtiming=t1-t0;
			
		}
		
		SetSurface(draw,Rect(ib.GetSize()),ib,ib.GetSize(),Point(0,0));
		
		double gain=(double)STtiming/(double)(0.1+MTtiming); // Avoid div by zero
		Title(Format("Rendering MT took %lld us, ST took %lld us, MT gain is %.2f",MTtiming,STtiming,gain));
	}
};

GUI_APP_MAIN
{
	PainterBench().Run();
}


There are two Serialized painting files to test with: SomeRocks.painting exhibits the MT slowdown issue dramatically. The other file is just for checking how fast a typical map view renders.

Best regards,

Tom
Re: Painter refactored/optimized [message #50558 is a reply to message #50557] Thu, 15 November 2018 10:48 Go to previous messageGo to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
OK, so the short answer: "It is too simple"

Less short answer: Most of time is spend allocating and cleaning per-thread dynamic data. MT is using up to 128 rasterizers, each rasterizer has to be allocated (~ 256KB) and after being used, it has to be "reset". I guess there is a lot of cache misses in the process, meanwhile ST runs in L1/L2 easily.

That said, I have some tricks in my mind to be implemented to fix this. The only trouble is that it involves changes to memory allocater, which is difficult...
Previous Topic: Jsonize/Xmlize with lambda (and common template example)
Next Topic: Critical issues to resolve for U++ 2018.1 - please suggest
Goto Forum:
  


Current Time: Thu Mar 28 16:19:08 CET 2024

Total time taken to generate the page: 0.01876 seconds