Tue Mar 18, 12:55:35, Marten Jan de Ruiter wrote
Now I have the following questions: Any idea why deallocation takes forever in the FE program as compared to allocation? Maybe the reason is that the data-structure is slightly more complicated than a linked list of integers ;-) How can I isolate the problem? What kind of feedback can I provide you with to isolate and solve the problem?
Gpc 20030209, based on gcc-3.2.1 does not compile the FE program, but that is another story, which is in my next mail.
Another gcc-3.2.1 based compiler does compile: gpc --version gpc 20021128, based on gcc-3.2.1 However, the profiling does not improve.
Flat profile:
Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 89.16 23.36 23.36 Preparedisposepointer 0.95 23.61 0.25 _p_read_longreal 0.84 23.83 0.22 _p_internal_getc
Wed Mar 19, 05:54:17, Frank Heckenbach wrote:
By default FreeMemPtr points to free(). I'm not sure if profiling includes subroutines (in particular, libc routines which probably were not compiled with `-pg'). If so, you could try to move the call into a subroutine to find out if free() or PrepareDisposePointer actually takes the time.
I do not know how exactly to do this. Here I insert some code that I expect to do it, and some relevant code for reference. However, I get an error: assignment from incompatible pointer type, because I do not know how to setup the pointer to my own routine.
Snippets from rts/heap.pas: procedure CFreeMem (aPointer: Pointer); asmname 'free'; ... FreeMemType = ^procedure (aPointer: Pointer); ... PMarkList = ^TMarkList; TMarkList = record Next, Prev : PMarkList; Marked : Boolean; MaxIndexUsed, PointersUsed: Integer; Entries : array [0 .. 255] of record Ptr : Pointer; PSize : SizeType; Caller: Pointer end end; ... FreeMemPtr : FreeMemType = @CFreeMem; asmname '_p_FreeMemPtr'; ... procedure PrepareDisposePointer (aPointer: Pointer); var p: PMarkList; ... FreeMemPtr^ (p) ...
program TestFree;
procedure CFreeMem (aPointer: Pointer); asmname 'free';
type LL_t = record {Linked List type} i : integer; next : ^LL_t; end;
FreeMemType = ^procedure (aPointer: Pointer);
PMarkList = ^TMarkList; TMarkList = record Next, Prev : PMarkList; Marked : Boolean; MaxIndexUsed, PointersUsed: Integer; Entries : array [0 .. 255] of record Ptr : Pointer; PSize : SizeType; Caller: Pointer end end;
var FreeMemPtr : FreeMemType = @CFreeMem; asmname '_p_FreeMemPtr'; OrigFreeMemPtr : FreeMemType; i : integer; LLfirst, LLcurrent, LLnew: ^LL_t;
procedure CallFreeEmjay(var p:PMarkList); begin OrigFreeMemPtr^(p); end;
begin {program}
{reroute the calls} OrigFreeMemPtr:=FreeMemPtr; FreeMemPtr:=@CallFreeEmjay; {Don't know how to do this???}
{test} new(LLfirst); {create first link} LLfirst^.i:=1; LLfirst^.next:=nil; LLcurrent:=LLfirst; {add other links} for i:=2 to 100000 do begin new(LLnew); LLnew^.i:=i; LLnew^.next:=LLcurrent^.next; LLcurrent^.next:=LLnew; LLcurrent:=LLcurrent^.next;\ end; {dispose all links again} LLnew:=nil; while LLfirst<> nil do begin LLcurrent:=LLfirst; {get the first link} LLfirst:=LLfirst^.next; {hold the second} dispose(LLcurrent) {throw away the first link} end;
end.