Forum > FPC development

[SOLVED]Improvement of packages/fcl-image/src/fpcanvas.inc TFPCustomCanvas.Erase

(1/2) > >>

lagprogramming:
packages/fcl-image/src/fpcanvas.inc contains the following procedure:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TFPCustomCanvas.Erase;var  x,y:Integer;begin  for x:=0 to Width-1 do    for y:=0 to Height-1 do      Colors[x,y]:=colTransparent;end; The following procedure should be faster. I've switched the for loops.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TFPCustomCanvas.Erase;var  x,y:Integer;begin  for y:=0 to Height-1 do    for x:=0 to Width-1 do      Colors[x,y]:=colTransparent;end;

Чебурашка:

--- Quote from: lagprogramming on March 23, 2023, 09:53:06 am ---packages/fcl-image/src/fpcanvas.inc contains the following procedure:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TFPCustomCanvas.Erase;var  x,y:Integer;begin  for x:=0 to Width-1 do    for y:=0 to Height-1 do      Colors[x,y]:=colTransparent;end; The following procedure should be faster. I've switched the for loops.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TFPCustomCanvas.Erase;var  x,y:Integer;begin  for y:=0 to Height-1 do    for x:=0 to Width-1 do      Colors[x,y]:=colTransparent;end;
--- End quote ---

I am curious to know what is the difference in terms of execution time, could you please explain/demonstrate?

lagprogramming:

--- Quote from: Чебурашка on March 23, 2023, 10:47:35 am ---I am curious to know what is the difference in terms of execution time, could you please explain/demonstrate?

--- End quote ---

It's a matter of CPU cache usage.
Original code "erases"(which in fact consists in writing data) all the lines(rows) of the canvas simultaneously. This means that the CPU will try to simultaneously cache writes for many lines, no more than the height of the canvas.
New CPUs have huge caches and good mechanisms of managing it, but old CPUs are not that good. Those old CPUs will run the proposed code faster than the original code because the data writes are leaner, more fluent.
Also, there are CPUs that write data forward significantly faster than writing it backward. This is another example of CPU cache usage.

Чебурашка:

--- Quote from: lagprogramming on March 23, 2023, 03:12:57 pm ---
--- Quote from: Чебурашка on March 23, 2023, 10:47:35 am ---I am curious to know what is the difference in terms of execution time, could you please explain/demonstrate?

--- End quote ---

It's a matter of CPU cache usage.
Original code "erases"(which in fact consists in writing data) all the lines(rows) of the canvas simultaneously. This means that the CPU will try to simultaneously cache writes for many lines, no more than the height of the canvas.
New CPUs have huge caches and good mechanisms of managing it, but old CPUs are not that good. Those old CPUs will run the proposed code faster than the original code because the data writes are leaner, more fluent.
Also, there are CPUs that write data forward significantly faster than writing it backward. This is another example of CPU cache usage.

--- End quote ---

Very interesting, thank you.

wp:
Here's a test project which measures the execution time for both methods. There's a 40% speed gain when y is in the outer loop (taking the case of x in the outer loop as a reference). Tested on a 10,000 x 10,000 pixel image.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1; uses  SysUtils, fpImage, fpCanvas, fpImgCanv; const  WIDTH = 10*1000;  HEIGHT = 10*1000;var  t: TDateTime;  img: TFPCustomImage;  cnv: TFPCustomCanvas;  i, x, y: Integer;begin  for i := 1 to 5 do  begin    WriteLn('Run #', i);    img := TFPMemoryImage.Create(WIDTH, HEIGHT);    try      cnv := TFPImageCanvas.Create(img);      try        Write('  outer loop x...: ');        t := Now;        for x:=0 to img.Width-1 do          for y:=0 to img.Height-1 do            cnv.Colors[x,y] := colTransparent;        t := Now-t;        WriteLn(FormatDateTime('s.zzz" seconds"', t));         Write('  outer loop y...: ');        t := Now;        for y:=0 to img.Height-1 do          for x:=0 to img.Width-1 do            cnv.Colors[x,y] := colTransparent;        t := Now-t;        WriteLn(FormatDateTime('s.zzz" seconds"', t));      finally        cnv.Free;      end;    finally      img.Free;    end;    WriteLn;  end;   Write('Done. Press ENTER to quit...');  ReadLn;end.
Post a patch to the FPC bug tracker, I doubt whether the developers taking care of graphics read this here.

Navigation

[0] Message Index

[#] Next page

Go to full version