Re: [fpc-pascal] Implementing AggPas with PtcGraph

2017-06-22 Thread Martin Schreiber
On Friday 23 June 2017 06:38:18 Martin Schreiber wrote:
> On Thursday 22 June 2017 18:47:40 James Richters wrote:
> > I squeezed a little more out of putimage by doing as little math as
> > possible with a couple of variables to store j*ptcwidth and i+j*ptcwidth 
> > I got my 1000x test loop down to 1.013 seconds.  Here is what it looks
> > like at the moment, any ideas on how to optimize it further?
>
> Please push your changes so we can work with the real code.
>
Sorry, I found it, it is in branch Avoid_ReChecking_Bitblt.

Martin


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Implementing AggPas with PtcGraph

2017-06-22 Thread Martin Schreiber
On Thursday 22 June 2017 18:47:40 James Richters wrote:
> I squeezed a little more out of putimage by doing as little math as
> possible with a couple of variables to store j*ptcwidth and i+j*ptcwidth  I
> got my 1000x test loop down to 1.013 seconds.  Here is what it looks like
> at the moment, any ideas on how to optimize it further?
>
Please push your changes so we can work with the real code.

Martin
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Implementing AggPas with PtcGraph

2017-06-22 Thread James Richters
I squeezed a little more out of putimage by doing as little math as possible 
with a couple of variables to store j*ptcwidth and i+j*ptcwidth  I got my 1000x 
test loop down to 1.013 seconds.  Here is what it looks like at the moment, any 
ideas on how to optimize it further?

 

https://github.com/Zaaphod/ptcpas/compare/master...Zaaphod_Custom#diff-fb31461e009ff29fda5c35c5115978b4

 

var

  pixels:Pword;

  k: longint;

  i, j, y1, x1, deltaX, deltaX1, deltaY: smallint;

  JxW, I_JxW: Longword;

..

XORPut: 

  Begin

for j:=Y to Y1 do

  Begin

JxW:=j*PTCWidth;

inc(k,deltaX);

for i:=X to X1 do

  begin

I_JxW:=i+JxW;

pixels[I_JxW] := pixels[I_JxW] xor pt(bitmap)[k];

inc(k);

  end;

inc(k,deltaX1);

  End;

  End;

..

 

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Implementing AggPas with PtcGraph

2017-06-22 Thread James Richters
>That sounds like a little bit of a special case - it'll work where you're 
>using putimage for a large area, that has very few pixels set. 

 

That is exactly what I have almost all the time.  I’m wanting to use putimage 
for the entire screen all the time, but very few pixels on the screen change at 
any given screen update.  I have already tried only using putimage for part of 
the screen, and that helps sometimes, but most of the time it doesn’t help 
enough, because I’ll be drawing a long diagonal line, or a big ellipse and to 
encase the entity in a rectangular shape ends using a good portion of the 
screen, and by the time I get done calculating how to make the only slightly 
smaller area, I might as well just did putimage on the entire screen.

 

>Perhaps just reimplementing the general algorithm in inline asm, by using SSE 
>(or MMX) vector instructions would be the fastest

 

That sounds completely over my head  

 

>but maybe it's not worth the pain

 

Maybe not…. I’m pretty sure I can handle processing the second array, but how 
and where to create it in aggpas, that I have no idea… yet… I have not actually 
tried to see how aggpas puts data in the buffer yet… It’s a huge package and 
I’m not sure what unit it’s even in.

 

>and the pascal implementation is fast enough for you.

 

It’s not quite fast enough yet…  

 

>Just experiment and see what works best :)

 

Sounds like fun    Maybe I’ll do a test and pre-build the second array myself, 
just to see if there is any real benefit to this whole idea and if there is 
then I’ll try to figure out how to do it with aggpas

 

>Btw, I looked at your code again and saw a quick and cheap optimization - just 
>move the case statement (case BitBlt of) outside the inner loop (for i:=X to 
>X1 do), so the value of BitBlt is not checked once every pixel, but once per 
>row.



Great Idea, I took it one step further, wanting it to be as fast as possible 
and only check BitBlt once for the entire nested loop.  I also made a combined 
procedure for both 8bpp and 16bpp.  This is about 7% faster. You can see it 
here:

https://github.com/Zaaphod/ptcpas/compare/Avoid_ReChecking_Bitblt#diff-fb31461e009ff29fda5c35c5115978b4

 

 

>Try rearranging that like this:

>..

>Code

>..

>Note that all array calculation and the case is removed from the inner most 
>loop, at the expense of duplicating the for loop. 

>The index is not used in the for loop and made 0 based to allow the tighest 
>FOR loop code generation.

 

I also tried this, but for some strange reason it’s slower.. clocking in at 
1.773s for my 1000x loop instead of 1.056s maybe I did something wrong.  Here 
is what I did:

https://github.com/Zaaphod/ptcpas/compare/Restructure_PutImage_Loop#diff-fb31461e009ff29fda5c35c5115978b4

maybe the two  inc(pdest); inc(psrc); inside the inner loop are slower than the 
inc(k)?

 

 

James

 

 





___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Implementing AggPas with PtcGraph

2017-06-22 Thread Marco van de Voort
In our previous episode, James Richters said:
> >putimage can be accelerated, although it would still have to do a memory 
> >copy.
> 
> Like this?
> https://github.com/Zaaphod/ptcpas/compare/Zaaphod_Custom?expand=1#diff-fb31461e009ff29fda5c35c5115978b4
> 
> This is amazingly faster.   I ran a test of just ptcgraph.putimage() in a
> loop, putting the same image over and over 1000 times and timing it.  The
> original ptcgraph.putimage() took 18.017 seconds.  After I applied this,
> the same loop took 1.056 seconds.  Quite an improvement!  It's still
> nowhere near as fast as just drawing stuff with ptcgraph directly, but for
> doing a memory copy of the entire screen, it's very fast

Try rearranging that like this:


var pdest,psrc: pword;
 

for j:=Y to Y1 do
   Begin
 inc(k,deltaX);
 pdest:=@pixels[X+j*PTCWidth];
 psrc:=@pt(bitmap)[k];
 case BitBlt of
   XORPut:   for i:=0 to X1-X do
   begin
 pdest^:=pdest^ xor psrc^;
 inc(pdest); inc(psrc);
   end;
  // etc other cases similarly
end;
 inc(k,x1-x+1); // we must make up for as many K updates as the for loop.
 inc(k,deltaX1);
end;

Note that all array calculation and the case is removed from the inner most
loop, at the expense of duplicating the for loop. The index is not used in
the for loop and made 0 based to allow the tighest FOR loop code generation.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Serial to TCP gateway in FPC?

2017-06-22 Thread Mark Morgan Lloyd

On 21/06/17 22:45, Bo Berglund wrote:


Two issues here:1) How do I enter a loop in a GUI application? In a command 
lineapplication it is just going to be part of he main program code.


I'm not saying it's the right or the best way, but in the interest of 
giving you something to work with I do this:



procedure TListForm.FormCreate(Sender: TObject);

CONST   startParam= 0;

begin
..
Application.QueueAsyncCall(@OnAfterShow, startParam) (* Keep at end *)
end { TListForm.FormCreate } ;


PROCEDURE TListForm.OnAfterShow(afterShowParam: PtrInt);

(* guaranteed to be after all form creation etc. has completed. *)

BEGIN
..
END { TListForm.OnAfterShow } ;


That can loop, but make sure you put Application.ProcessMessages in it.

--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal