Re: [fpc-devel] Class field reordering

2012-07-21 Thread Martin

On 14/07/2012 20:46, Jonas Maebe wrote:

That may actually lead to quite some troubles: if someone recompiles the RTL without 
optimizations, then your class crackers also have to change that setting. And there's no 
way to detect how the RTL (or in general: units containing classes you are 
cracking) has been compiled in your source code.


Actually there may be:

The cracking unit, needs both cracker classes (with and without 
optimization).


If sizeof(TOptimizedCracker)=sizeof(TTheClass) then
If sizeof(TNotOptimizedCracker)=sizeof(TTheClass) then

This will however not work, if reordering happens for performance.
It could also not work, if the optimizer reorders fields, even if it 
does not save space in the end. (not sure if that can happen).



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-19 Thread Skybuck Flying
 I also wonder how much of an optimization it actually is ? Maybe 
 0.01%

 more performance ?


1) as mentioned in the original mail, the current transformation is
implemented for saving memory, not for improving performance


This wasn't clear, it only mentions gaps. What kind of gaps ?



Gaps between fields of an object instance due to alignment. Typically
loading data from unaligned address, i.e. an address that is not evenly
divisible by the field size, is slower than otherwise. Also, some CPU
architectures even give you an exception if you actually try.

E.g. for the following object

type
 test = class
   b1 : byte;
   d : double;
   b2 : byte;
   q : qword;
 end;

due to above hardware limitations an instance will look as follows in
memory (first column indicates offset, disregarding any additional
internal data):

0:  b1
1-7  : empty
8-15 : d
16   : b2
17-23: empty
24-31: q

So for storing 18 bytes of usable data, you use up 32 bytes in memory,
i.e. a waste of 44%.
Now imagine your program uses thousands of these records.


If it was in a record then that's what a packed record is for.

Perhaps pascal should be extended with packed class.

I would like something like that... it makes more sense then some 
weird/automatic/black box behaviour ;)



I scanned over this document and it seems to mention profiling
information, it also mentions compilers which can then use this 
profiling

information to re-arrange fields.

To me it seems this optimization idea belongs in the realm of profilers.
It should be easy for a programmer to use such a profiling tool and make 
the

necessary changes him/herself instead of complexifieing the compiler.

[.. snipped the rest...]



Imo for a static compiler like fpc, re-arranging fields for pure
performance reasons without reasonably accurate profiling information is
indeed pure guesswork.
I do not see a problem with automating this process.


I do see a bit of a problem with it. Computer programs can have many 
options/variables which could have all kinds of values.


It's probably not practical to try every possible value because this would 
take to long.


So automating it will be problematic.


 I rarely inspect the binary equivalent of a class instance, so your
 supposedly optimization is probably not a big deal, for records that 
 would

 be a different matter since these are used in all kinds of api's and
 input/output situations.


As mentioned in the original mail, the transformation would only be 
applied

to classes.


How is a record not an abstraction and a class is an abstraction, that's
kinda weird/inconsistent ?!



Because unfortunately people are already (mis-)using records by
blockwriting/reading them without knowing that this is not portable at
all.
Actually such things already break e.g. when moving from 32 to 64 bit
processors, or from one cpu architecture to another with different
alignment rules, and so on. When 64 bit was new, there have been many
questions/issues about exactly that - on this list too.

It looks like a purely pragmatic decision. (And maybe sometime somewhere
the Borland people defined it that way for records).


Does this apply to packed records ? I would hope not.


 It's already bad that Delphi adds invisible fields to classes so they
 cannot be simply dumped to disk... (virtual method table pointers ?)
 this would make it even worse.

 If you want to program at an assembler level of abstraction, don't use
 high level language features.

 I see no reason why a high level language could not be used to produce
 binary instructions and or files/data.


It can be used for that, as long as you don't use high level abstractions.
The whole point of abstractions to get rid of any guarantees a far as
implementation is concerned, in order to increase portability, programmer
productivity and compiler optimization opportunities.


How about instead extending the pascal language description and 
specifieing

that the order of the fields in the class and records must be the same in
binary as well. This seems nice and constant and might allow some other
functionalities in the future.
That is not to say that this supposedly optimization could be done and
later then removed if this order extension is introduced.



Given that not fixing the order has above mentioned tangible advantages
right now, and fixing the layout only some unknown ones in the future,
it seems the better choice to not do it. Also because it can still be
specified in the future if needed :)

So we agree.


Not really, if features/optimizations are implemented which need to be 
removed in the future then that is again a lot of work to do.


Simply removing stuff/code takes time/energy/work as well.

Bye,
 Skybuck. 


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread Martin Schreiber
On Tuesday 17 July 2012 09:40:36 michael.vancann...@wisa.be wrote:
  Maybe, but what about performance? Another complication is the
  updatebuffer with the oldvalues.

 Thinking about it:

 I would allocate the buffer as is, with for all string fields an
 integer-sized slot in the buffer. The slot contains an index, pointing
 to a separate array of strings containing  N*M*2 strings. (N=number of
 records, M= Number of string fields per record, factor 2 for old values)

 Field value =  Element [Index  [+1 for old value]] in the array.
 where the [Index] is stored in the buffer.

 The speed performance penalty of this system should be negligable, since
 you assume all records are in memory anyway.

 And: everything can be done without meddling with the internals of TField.

Thank you. There are more items in the db.pas list...
But I think first we should concentrate on classes.pas because I really don't 
want to fork it. Forking db.pas is less problematic and I probably prefer it 
in place of an endless discussion and in my eyes not optimal solutions. With 
a forked db.pas I can eliminate the many workarounds I already had to 
implement.

Currently needed crackerclasses by MSEide+MSEgui:

Used by MSEide for different tasks (example: ask for ancestor forms and 
frames/submodules while loading a form/datamodule, recover in case of an 
error) and for streaming of frames with additional components/widgets:

TComponent:
- FComponents
- FComponentState
- FFreeNotifies

TWriter:
- FPropPath
- FAncestors

TReader:
- FStream
- FLoaded

Used in order TParams create tmseparam items instead of TParam:

TCollection:
- FItemClass

Used to unify memorystreams/files/pipes/sockets/stringstreams:

THandlestream:
- FHandle

TMemoryStream:
- FCapacity

Why must these fields be private?

Thanks, Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread Martin Schreiber
On Wednesday 18 July 2012 08:19:02 Martin Schreiber wrote:
 Used in order TParams create tmseparam items instead of TParam:

 TCollection:
 - FItemClass

Probably can be solved in a forked db.pas

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread michael . vancanneyt



On Wed, 18 Jul 2012, Martin Schreiber wrote:


On Tuesday 17 July 2012 09:40:36 michael.vancann...@wisa.be wrote:

Maybe, but what about performance? Another complication is the
updatebuffer with the oldvalues.


Thinking about it:

I would allocate the buffer as is, with for all string fields an
integer-sized slot in the buffer. The slot contains an index, pointing
to a separate array of strings containing  N*M*2 strings. (N=number of
records, M= Number of string fields per record, factor 2 for old values)

Field value =  Element [Index  [+1 for old value]] in the array.
where the [Index] is stored in the buffer.

The speed performance penalty of this system should be negligable, since
you assume all records are in memory anyway.

And: everything can be done without meddling with the internals of TField.


Thank you. There are more items in the db.pas list...
But I think first we should concentrate on classes.pas because I really don't
want to fork it. Forking db.pas is less problematic and I probably prefer it
in place of an endless discussion and in my eyes not optimal solutions. With
a forked db.pas I can eliminate the many workarounds I already had to
implement.


Currently needed crackerclasses by MSEide+MSEgui:

Used by MSEide for different tasks (example: ask for ancestor forms and
frames/submodules while loading a form/datamodule, recover in case of an
error) and for streaming of frames with additional components/widgets:

TComponent:
- FComponents
- FComponentState
- FFreeNotifies


Descendent classes should not manipulate these except through the right
methods such as insert/remove component and FreeNotification/RemoveFreeNotification ? 
You have the means to manipulate the contents, what is wrong ?




TWriter:
- FPropPath
- FAncestors


I see no problem in making these available as read-only protected
properties.



TReader:
- FStream
- FLoaded

Used in order TParams create tmseparam items instead of TParam:

TCollection:
- FItemClass


A collection must always contain the same items. The class is determined
when the collection is instantiated.



Used to unify memorystreams/files/pipes/sockets/stringstreams:

THandlestream:
- FHandle


The handle is fixed throughout the lifetime of the stream. It is set when
creating the stream, and closed when destroying the stream.



TMemoryStream:
- FCapacity



What is wrong with the r/w property Capacity ?

I think you are missing an important point:

You want some radical changes, so I expect you to be the one giving the 
reasons/motivations for a change. I want to help find solutions, but not
at the price of destroying what is in my eyes a correctly constructed class 
hierarchy.


If you don't give a detailed explanation why you need to manipulate 
all these private fields outside of the proper methods, then I cannot 
help you find solutions for the problems you experience, so please:

elaborate.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread michael . vancanneyt



On Wed, 18 Jul 2012, Martin Schreiber wrote:


On Wednesday 18 July 2012 08:19:02 Martin Schreiber wrote:

Used in order TParams create tmseparam items instead of TParam:

TCollection:
- FItemClass


Probably can be solved in a forked db.pas


Or by 2 other solutions:

* having a global variable ParamsClass : TParamsClass and use that whenever a 
TParams instance is created.

* Or have a virtual function CreateParams which is used everywhere.

There are always other solutions.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread Martin Schreiber
On Wednesday 18 July 2012 09:43:16 michael.vancann...@wisa.be wrote:
 On Wed, 18 Jul 2012, Martin Schreiber wrote:
  On Wednesday 18 July 2012 08:19:02 Martin Schreiber wrote:
  Used in order TParams create tmseparam items instead of TParam:
 
  TCollection:
  - FItemClass
 
  Probably can be solved in a forked db.pas

 Or by 2 other solutions:

 * having a global variable ParamsClass : TParamsClass and use that whenever
 a TParams instance is created.

 * Or have a virtual function CreateParams which is used everywhere.

 There are always other solutions.

I meant it can be solved without you need to change anything.

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread Martin Schreiber
On Wednesday 18 July 2012 09:33:09 michael.vancann...@wisa.be wrote:

 I think you are missing an important point:

 You want some radical changes, so I expect you to be the one giving the
 reasons/motivations for a change. I want to help find solutions, but not
 at the price of destroying what is in my eyes a correctly constructed class
 hierarchy.

 If you don't give a detailed explanation why you need to manipulate
 all these private fields outside of the proper methods, then I cannot
 help you find solutions for the problems you experience, so please:
 elaborate.

If I only could be sure that it is worth the effort...

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread michael . vancanneyt



On Wed, 18 Jul 2012, Martin Schreiber wrote:


On Wednesday 18 July 2012 09:33:09 michael.vancann...@wisa.be wrote:


I think you are missing an important point:

You want some radical changes, so I expect you to be the one giving the
reasons/motivations for a change. I want to help find solutions, but not
at the price of destroying what is in my eyes a correctly constructed class
hierarchy.

If you don't give a detailed explanation why you need to manipulate
all these private fields outside of the proper methods, then I cannot
help you find solutions for the problems you experience, so please:
elaborate.


If I only could be sure that it is worth the effort...


Does this mean you're not even going to try ?

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread Martin Schreiber
On Wednesday 18 July 2012 10:50:36 michael.vancann...@wisa.be wrote:

  If you don't give a detailed explanation why you need to manipulate
  all these private fields outside of the proper methods, then I cannot
  help you find solutions for the problems you experience, so please:
  elaborate.
 
  If I only could be sure that it is worth the effort...

 Does this mean you're not even going to try ?

I'll think about.
Thank you for your time.

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread Sven Barth
Am 18.07.2012 10:08 schrieb Martin Schreiber mse00...@gmail.com:

 On Wednesday 18 July 2012 09:33:09 michael.vancann...@wisa.be wrote:

  I think you are missing an important point:
 
  You want some radical changes, so I expect you to be the one giving the
  reasons/motivations for a change. I want to help find solutions, but not
  at the price of destroying what is in my eyes a correctly constructed
class
  hierarchy.
 
  If you don't give a detailed explanation why you need to manipulate
  all these private fields outside of the proper methods, then I cannot
  help you find solutions for the problems you experience, so please:
  elaborate.
 
 If I only could be sure that it is worth the effort...

Though there is the saying that forks aren't bad, I'd say that the less
units forked the better. The Pascal community is already small enough so we
should not fragment regarding such base units like db.
Also in my opinion the less hacks (that could prevent optimizations) the
better.

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread Luiz Americo Pereira Camara

Em 18/7/2012 03:19, Martin Schreiber escreveu:

Thank you. There are more items in the db.pas list...
But I think first we should concentrate on classes.pas because I really don't
want to fork it. Forking db.pas is less problematic and I probably prefer it
in place of an endless discussion and in my eyes not optimal solutions. With
a forked db.pas I can eliminate the many workarounds I already had to
implement.

Currently needed crackerclasses by MSEide+MSEgui:


I also have somethings in fpc rtl/fcl that also don't like or changing 
would simplify my work. But if we start to change base classes at each 
developer request we may end with a mess.
Just to be clear, i'm not against all changes. Some specific points can 
be changed at  careful examination (like devs are already doing)


BTW: some time ago you pointed  in a fpc list that will not use trunk 
because of encoding aware strings, so you don't need to worry because 
the trunk changes won't affect you anyway


Luiz


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-18 Thread Martin Schreiber
On Thursday 19 July 2012 05:13:01 Luiz Americo Pereira Camara wrote:

 I also have somethings in fpc rtl/fcl that also don't like or changing
 would simplify my work. But if we start to change base classes at each
 developer request we may end with a mess.
 Just to be clear, i'm not against all changes. Some specific points can
 be changed at  careful examination (like devs are already doing)

I don't think moving fields from private to protected in order it is possible 
to implement the wanted behaviour in my library need careful examination 
because it does not touch the FPC functionality.

I *never* asked to change *any* functionality in FPC-RTL other than to fix 
bugs which could be demonstrated by a different behaviour to Delphi 7!
And I had no problems to use cracker classes and mad workarounds on my own 
risk in order not to bother the FPC team with my needs.
The problem now is that cracker classes can't be used in future anymore 
because of the new class field ordering optimisation, so I dared to ask.
 
 BTW: some time ago you pointed  in a fpc list that will not use trunk
 because of encoding aware strings, so you don't need to worry because
 the trunk changes won't affect you anyway

At the moment.
I hope sometimes in the future the FPC team can say the dust has settled down 
now and the Unicode handling in FPC is/will be done so and so.
I do not want to adapt MSEgui to a moving target.

BTW: does anybody know how unicode resourcestrings work or are planned to work 
in FPC trunk?

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-17 Thread michael . vancanneyt



On Tue, 17 Jul 2012, Martin Schreiber wrote:


On Monday 16 July 2012 17:25:58 michael.vancann...@wisa.be wrote:

On Mon, 16 Jul 2012, Martin Schreiber wrote:

On Monday 16 July 2012 16:50:06 michael.vancann...@wisa.be wrote:

Well, from your code adding the following to the protected section:

   Property ValueBuffer : Pointer Read FValueBuffer;
   Property Validating : Boolean Read FValidating ;

Should be enough to remove the need for the TFieldCracker ?


Unfortunately no:

procedure tmsebufdataset.checkfreebuffer(const afield: tfield);
begin
{$ifdef FPC}{$warnings off}{$endif}
with tfieldcracker(afield) do begin
{$ifdef FPC}{$warnings on}{$endif}
 if foffset and 2  0 then begin
  freemem(fvaluebuffer);
  fvaluebuffer:= nil;
 end;
end;
end;



If I understand correctly, you have in the record buffer just the pointer
of the (wide)string instead of the actual string data ?


Correct. The UnicodeString pointer. That has not directly to do with the
procedure above BTW. This one is to allow changing field values in OnValidate
IIRC.


If so, why then didn't you implement the string fields as blobs are
implemented in SQLDB (it is basically the same problem), in that case you
would not need the internal fields of TField at all ?


Maybe, but what about performance? Another complication is the updatebuffer
with the oldvalues.


Thinking about it:

I would allocate the buffer as is, with for all string fields an
integer-sized slot in the buffer. The slot contains an index, pointing 
to a separate array of strings containing  N*M*2 strings. (N=number of 
records, M= Number of string fields per record, factor 2 for old values)


Field value =  Element [Index  [+1 for old value]] in the array. 
where the [Index] is stored in the buffer.


The speed performance penalty of this system should be negligable, since you
assume all records are in memory anyway.

And: everything can be done without meddling with the internals of TField.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-17 Thread Skybuck Flying

I don't think this is a good idea.

For example while debugging and looking at the memory in raw this would 
lead to confusion.


By knowing the order of the fields, you still don't know their exact 
offsets. If you want to know their address, print 
@classinstance.fieldname


Yes but I do know the order of the fields which does help make some sense 
of it. With your suggested optimizations it would become much more 
confusing/mixed/shuffled.


I also find it slightly strange how there is now an even bigger disconnect 
between records and classes.



The whole point of classes is to offer abstraction. Again: if you don't want 
abstraction, don't use data structures that offer an abstraction.



I have a different view on programming languages and pascal. It's a tool to 
help generate code. The abstraction is to prevent tieing to a single 
instruction set/cpu/computer, but it's always nice if the 
result/instructions/data field can be compared to the high level code.


I also wonder how much of an optimization it actually is ? Maybe 0.01% 
more performance ?



1) as mentioned in the original mail, the current transformation is 
implemented for saving memory, not for improving performance



This wasn't clear, it only mentions gaps. What kind of gaps ? Apperently you 
ment to minimize memory size, the opposite could also have been ment in the 
sense of optimizations to make fields fall on memory boundaries for perhaps 
increased fetch speed or something else.


Later performance optimization possibilities for the future are mentioned as 
well.



2) if it was done for performance reasons, some people already got up to 34% 
extra performance by doing exactly that: 
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.4009 (download 
the cached version of the paper, the original link no longer works)



I scanned over this document and it seems to mention profiling 
information, it also mentions compilers which can then use this profiling 
information to re-arrange fields.


To me it seems this optimization idea belongs in the realm of profilers. 
It should be easy for a programmer to use such a profiling tool and make the 
necessary changes him/herself instead of complexifieing the compiler.


Perhaps someday these kinds of complex optimization tricks might backfire 
as well, because of different runs of the program or so, though usually 
there is some redline in a program.


How do you envision this profiling to be done with the free pascal compiler 
or did you think about some kind of static offline optimization ?


If the later how about this:


setup code:

access field 2.

access field 2

red loop:

forever access field1 then field2.


Without actually running the code and profiling it or analyzing the for 
loop, the static offline optimization trick would believe field2 is accessed 
the most while field1 is actually accessed the most first.


So could lead to wrong optimization results.

I rarely inspect the binary equivalent of a class instance, so your 
supposedly optimization is probably not a big deal, for records that would 
be a different matter since these are used in all kinds of api's and 
input/output situations.



As mentioned in the original mail, the transformation would only be applied 
to classes.



How is a record not an abstraction and a class is an abstraction, that's 
kinda weird/inconsistent ?!


It's already bad that Delphi adds invisible fields to classes so they 
cannot be simply dumped to disk... (virtual method table pointers ?) 
this would make it even worse.


If you want to program at an assembler level of abstraction, don't use 
high level language features.


I see no reason why a high level language could not be used to produce 
binary instructions and or files/data.



It can be used for that, as long as you don't use high level abstractions. 
The whole point of abstractions to get rid of any guarantees a far as 
implementation is concerned, in order to increase portability, programmer 
productivity and compiler optimization opportunities.



How about instead extending the pascal language description and specifieing 
that the order of the fields in the class and records must be the same in 
binary as well. This seems nice and constant and might allow some other 
functionalities in the future.


That is not to say that this supposedly optimization could be done and later 
then removed if this order extension is introduced.


Finally I do see some merit for free pascal compiler or any other compiler 
to generate some helpfull (debugging?) / profiling information (?) so that a 
profiler can report back to the user what source code fields are accessed 
and in what order... and how often to give some hints or suggestions to the 
programmer how to make the optimizations him/herself.


Some might even take fun in optimization code, but it can also be boring 
work, then again, after having done it a few times, perhaps programmers 
learn from it and become better 

Re: [fpc-devel] Class field reordering

2012-07-17 Thread Thomas Schatzl
Hi,

On Tue, 2012-07-17 at 08:22 +0200, Skybuck Flying wrote:
  I also wonder how much of an optimization it actually is ? Maybe 0.01% 
  more performance ?
 
 
 1) as mentioned in the original mail, the current transformation is 
 implemented for saving memory, not for improving performance
 
 
 This wasn't clear, it only mentions gaps. What kind of gaps ? 

Gaps between fields of an object instance due to alignment. Typically
loading data from unaligned address, i.e. an address that is not evenly
divisible by the field size, is slower than otherwise. Also, some CPU
architectures even give you an exception if you actually try.

E.g. for the following object

type
  test = class
b1 : byte;
d : double;
b2 : byte;
q : qword;
  end;

due to above hardware limitations an instance will look as follows in
memory (first column indicates offset, disregarding any additional
internal data):

0:  b1
1-7  : empty
8-15 : d
16   : b2
17-23: empty
24-31: q

So for storing 18 bytes of usable data, you use up 32 bytes in memory,
i.e. a waste of 44%.
Now imagine your program uses thousands of these records.

 Apperently you 
 ment to minimize memory size, the opposite could also have been ment in the 
 sense of optimizations to make fields fall on memory boundaries for perhaps 
 increased fetch speed or something else.

You always want to make fields fall on memory boundaries (i.e. align
them) except if you are either really scarce on memory, need a specific
layout for i/o purposes or have another reason to do so (e.g. extra
padding in multi-threaded code when you want to avoid cache line
contention).

But then hopefully you know what you need to take care of and read the
manual. There is a way to disable this reordering on a per-class basis.

 Later performance optimization possibilities for the future are mentioned as 
 well.

Given that software on reasonably modern hardware is very often memory
bound, a decrease in memory footprint often translates into real
performance gains.

In the above case, if this optimization is applied, the object
instance looks as follows (for example, do not know the exact
algorithm):

0-7  : d
8-15 : q
16   : b1
17   : b2

I.e. the object now uses exactly 18 bytes of memory.


 
 2) if it was done for performance reasons, some people already got up to 34% 
 extra performance by doing exactly that: 
 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.4009 (download 
 the cached version of the paper, the original link no longer works)
 
 
 I scanned over this document and it seems to mention profiling 
 information, it also mentions compilers which can then use this profiling 
 information to re-arrange fields.
 
 To me it seems this optimization idea belongs in the realm of profilers. 
 It should be easy for a programmer to use such a profiling tool and make the 
 necessary changes him/herself instead of complexifieing the compiler.

 [.. snipped the rest...]

Imo for a static compiler like fpc, re-arranging fields for pure
performance reasons without reasonably accurate profiling information is
indeed pure guesswork.
I do not see a problem with automating this process.

However as mentioned above, decreasing memory footprint often also
increases performance.

  I rarely inspect the binary equivalent of a class instance, so your 
  supposedly optimization is probably not a big deal, for records that would 
  be a different matter since these are used in all kinds of api's and 
  input/output situations.
 
 
 As mentioned in the original mail, the transformation would only be applied 
 to classes.
 
 
 How is a record not an abstraction and a class is an abstraction, that's 
 kinda weird/inconsistent ?!

Because unfortunately people are already (mis-)using records by
blockwriting/reading them without knowing that this is not portable at
all.
Actually such things already break e.g. when moving from 32 to 64 bit
processors, or from one cpu architecture to another with different
alignment rules, and so on. When 64 bit was new, there have been many
questions/issues about exactly that - on this list too.

It looks like a purely pragmatic decision. (And maybe sometime somewhere
the Borland people defined it that way for records).

  It's already bad that Delphi adds invisible fields to classes so they 
  cannot be simply dumped to disk... (virtual method table pointers ?) 
  this would make it even worse.
 
  If you want to program at an assembler level of abstraction, don't use 
  high level language features.
 
  I see no reason why a high level language could not be used to produce 
  binary instructions and or files/data.
 
 
 It can be used for that, as long as you don't use high level abstractions. 
 The whole point of abstractions to get rid of any guarantees a far as 
 implementation is concerned, in order to increase portability, programmer 
 productivity and compiler optimization opportunities.
 
 
 How about instead extending the pascal language 

Re: [fpc-devel] Class field reordering

2012-07-16 Thread michael . vancanneyt



On Sun, 15 Jul 2012, Martin Schreiber wrote:


On Sunday 15 July 2012 19:21:58 Michael Van Canneyt wrote:

On Sun, 15 Jul 2012, Martin Schreiber wrote:

Currently I need access to the following private FCL class fields because
of MSEide+MSEgui extensions:


I have looked at your list. (I sent my previous mail about this without
having seen the list)

At first sight, I see no reason to make any of these fields protected.


Jup, I feared it. ;-)


I wrote 'at first sight', because without explanation I don't know what you
try to achieve.




For example:
TParam.FBound
Is directly accessible through TParam.Bound, so why on earth would you need
to have it protected ??


Hmm, this probably is a mistake from me. Was it writeable in all FPC versions?


This I don't know. At least, now it is writable.




Can you give some explanations at least of what you're trying to do,
maybe we can find workarounds for your problems ?


Before I started to use cracker classes I searched workarounds for weeks or
even months already...


2 pairs of eyes always see more than one.


If you want you can grep the MSEide+MSEgui sources for cracker in order see
what I do with them.


That does not tell me why you do something ?


TComponent, TWriter, TReader for example because in
MSEide+MSEgui one can place additional components in an inserted tframe and
combination of inherited frames and inherited forms need special handling.


Basically, you want to drop a component on a Form containing a frame, and make 
it's owner the frame ?



The DB components mainly because MSEgui stores string fields as UnicodeString
in datasets and because of the direct data access by index without scrolling.


So you take away the concept of cursor. That is a radical change.
This assumes that all records are always in memory ?

The string fields should not necessitate the access of private fields, you can 
just always create TWideStringField instances ? 
Maybe we need a function to decide the class of a string field ?




The stream components because in MSEgui there is a single hierarchy for file
and memory stream so the more specialized descendants (ttextstream,
ttextdatastream) can work on files and on memory.


I'm sorry, I don't understand what this means ?

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Skybuck Flying



-Original Message- 
From: Jonas Maebe

Sent: Sunday, July 15, 2012 15:49
To: FPC developers' list
Subject: Re: [fpc-devel] Class field reordering


On 14 Jul 2012, at 14:16, Skybuck Flying wrote:


I don't think this is a good idea.

For example while debugging and looking at the memory in raw this would 
lead to confusion.



By knowing the order of the fields, you still don't know their exact 
offsets. If you want to know their address, print @classinstance.fieldname



Yes but I do know the order of the fields which does help make some sense of 
it. With your suggested optimizations it would become much more 
confusing/mixed/shuffled.


I also find it slightly strange how there is now an even bigger disconnect 
between records and classes.


I also wonder how much of an optimization it actually is ? Maybe 0.01% 
more performance ?


I rarely inspect the binary equivalent of a class instance, so your 
supposedly optimization is probably not a big deal, for records that would 
be a different matter since these are used in all kinds of api's and 
input/output situations.


I still find your suggested optimization weird though. CPU cache lines as 
far as I know are 64 bytes or so... Let's assume a class with 10 fields each 
4 bytes long, that's 40 bytes.


How would re-ordering fields lead to faster performance ? I don't really see 
that...


It's already bad that Delphi adds invisible fields to classes so they 
cannot be simply dumped to disk... (virtual method table pointers ?) this 
would make it even worse.



If you want to program at an assembler level of abstraction, don't use high 
level language features.



I see no reason why a high level language could not be used to produce 
binary instructions and or files/data.


Bye,
 Skybuck. 


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Sven Barth
Am 14.07.2012 01:45 schrieb Jonas Maebe jonas.ma...@elis.ugent.be:


 Hi,

 I've implemented an optimization that reorders the instance fields of
Delphi-style classes (and only of Delphi-style classes) to minimise memory
gaps caused by alignment differences and odd sizes. The effect is the same
as when you would change the order of the fields in the source code to
achieve this effect.

 In general, I think this should be safe since unlike records and TP-style
objects, a Delphi class is normally never blockwritten to disk or so. There
is a switch to disable this transformation, but I'm wondering whether
anyone sees a problem with enabling it by default when -O2 or higher is
used.

 It works fine with at least the compiler and Lazarus without any ill
effects, saving a small amount of memory for both (about 2.5MB on 87MB for
the Darwin/x86-64 compiler compiling itslf, and 2.5MB on 62.7MB for a
Carbon/i386 Lazarus right after startup and loading some source files).


 Jonas

 PS: a similar reordering could be performed for local variables, although
the implementation would be quite different. Additionally, different kinds
of reordering, e.g. targeting cache improvements by putting fields/local
variables often used together next to each other, could also be implemented
in the future.

While reading Skybuck's second mail I got a thought: does this optimization
also apply on systems that require proper alignment for memory accesses?

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Jonas Maebe

On 16 Jul 2012, at 09:22, Skybuck Flying wrote:

 -Original Message- From: Jonas Maebe
 Sent: Sunday, July 15, 2012 15:49
 To: FPC developers' list
 Subject: Re: [fpc-devel] Class field reordering
 
 
 On 14 Jul 2012, at 14:16, Skybuck Flying wrote:
 
 I don't think this is a good idea.
 
 For example while debugging and looking at the memory in raw this would 
 lead to confusion.
 
 By knowing the order of the fields, you still don't know their exact 
 offsets. If you want to know their address, print @classinstance.fieldname
 
 Yes but I do know the order of the fields which does help make some sense of 
 it. With your suggested optimizations it would become much more 
 confusing/mixed/shuffled.
 
 I also find it slightly strange how there is now an even bigger disconnect 
 between records and classes.

The whole point of classes is to offer abstraction. Again: if you don't want 
abstraction, don't use data structures that offer an abstraction.

 I also wonder how much of an optimization it actually is ? Maybe 0.01% 
 more performance ?

1) as mentioned in the original mail, the current transformation is implemented 
for saving memory, not for improving performance
2) if it was done for performance reasons, some people already got up to 34% 
extra performance by doing exactly that: 
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.4009 (download the 
cached version of the paper, the original link no longer works)

 I rarely inspect the binary equivalent of a class instance, so your 
 supposedly optimization is probably not a big deal, for records that would be 
 a different matter since these are used in all kinds of api's and 
 input/output situations.

As mentioned in the original mail, the transformation would only be applied to 
classes.

 It's already bad that Delphi adds invisible fields to classes so they 
 cannot be simply dumped to disk... (virtual method table pointers ?) this 
 would make it even worse.
 
 If you want to program at an assembler level of abstraction, don't use high 
 level language features.
 
 I see no reason why a high level language could not be used to produce binary 
 instructions and or files/data.

It can be used for that, as long as you don't use high level abstractions. The 
whole point of abstractions to get rid of any guarantees a far as 
implementation is concerned, in order to increase portability, programmer 
productivity and compiler optimization opportunities.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Jonas Maebe

On 16 Jul 2012, at 13:14, Sven Barth wrote:

 does this optimization
 also apply on systems that require proper alignment for memory accesses?

Well, yes, otherwise the optimization would simply consist of removing all 
alignment padding and there would be no need to reorder the fields.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Mattias Gaertner
On Mon, 16 Jul 2012 09:35:16 +0200 (CEST)
michael.vancann...@wisa.be wrote:

[...]
  TComponent, TWriter, TReader for example because in
  MSEide+MSEgui one can place additional components in an inserted tframe and
  combination of inherited frames and inherited forms need special handling.
 
 Basically, you want to drop a component on a Form containing a frame, and 
 make 
 it's owner the frame ?

I guess he meant adding a component with 
Owner=Form, Parent=nested frame
As far as I remember TReader (or TWriter I'm not sure) does not support
this. Lazarus artificially forbids this too. Internally most code
supports this. 

Martin, what do you mean with combination of inherited frames and
inherited forms need special handling ?

[...]

Mattias
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread michael . vancanneyt



On Mon, 16 Jul 2012, Mattias Gaertner wrote:


On Mon, 16 Jul 2012 09:35:16 +0200 (CEST)
michael.vancann...@wisa.be wrote:


[...]

TComponent, TWriter, TReader for example because in
MSEide+MSEgui one can place additional components in an inserted tframe and
combination of inherited frames and inherited forms need special handling.


Basically, you want to drop a component on a Form containing a frame, and make
it's owner the frame ?


I guess he meant adding a component with
Owner=Form, Parent=nested frame
As far as I remember TReader (or TWriter I'm not sure) does not support
this. Lazarus artificially forbids this too. Internally most code
supports this.


I see no reason why TWriter would not support this, because it uses
GetChildren to get the list of children ? There must be something else.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Nico Erfurth
On 16.07.12 09:22, Skybuck Flying wrote:

 I also wonder how much of an optimization it actually is ? Maybe
 0.01% more performance ?

Cache related optimizations are VERY hard to measure and depend on
overall context and used architecture. But as the L1-cache is one of the
most performance critical parts in these days cpus the gains of working
with cache friendly structures should not be underestimated.

There a a couple of things that need to be taken into account.

1.) Cacheline Utilization: Packing together multiple smaller items into
single (machine-)words allows for better utilization of precious cache
space. As L1-DCache is usually only 16-32kbytes these days, every byte
counts, because saving a single byte can make a difference between using
one or two cache lines, which in return will save memory bandwidth and
save you from a cache-miss related stall down the line.

2.) Cacheline Streaming: unless your memory bus is a wide as your
cacheline it takes multiple cycles to fetch a whole cacheline. The
pipeline has to stall till the data in question arrives. If you have
relevant data in the end of a cacheline you will have to wait for the
whole transaction to complete. So it makes sense to order fields by
occurence of access so your first miss will hopefully only lead to the
minimal stall time.

While modern CPUs can circumvent/hide some of the cache miss latency
with the help of prefetching, out-of-order execution and Hyperthreading
it will still lead to a performance penalty. For CPUs without these
features (like most ARM cores) this penalty can become substantial,
leading to 100 and more stall cycles for a cache-miss.

Nico
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Martin Schreiber
On Monday 16 July 2012 14:08:23 Mattias Gaertner wrote:
 On Mon, 16 Jul 2012 09:35:16 +0200 (CEST)

 michael.vancann...@wisa.be wrote:
 [...]
 
   TComponent, TWriter, TReader for example because in
   MSEide+MSEgui one can place additional components in an inserted tframe
   and combination of inherited frames and inherited forms need special
   handling.
 
  Basically, you want to drop a component on a Form containing a frame, and
  make it's owner the frame ?

 I guess he meant adding a component with
 Owner=Form, Parent=nested frame
 As far as I remember TReader (or TWriter I'm not sure) does not support
 this. Lazarus artificially forbids this too. Internally most code
 supports this.

Correct.

 Martin, what do you mean with combination of inherited frames and
 inherited forms need special handling ?

I don't remember exactly and I don't want to remember because of too much 
headache. ;-)
Assume frames which had inserted forms (in MSEgui every form or datamodule can 
act as TFrame, MSEgui has no specific TFrame component), which where 
inherited and there are descendants which are inserted into a form which 
possibly has descendants too...

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Martin Schreiber
On Monday 16 July 2012 09:35:16 michael.vancann...@wisa.be wrote:

  The DB components mainly because MSEgui stores string fields as
  UnicodeString in datasets and because of the direct data access by index
  without scrolling.

 So you take away the concept of cursor. That is a radical change.

The cursor concept still exists, direct access without scrolling is an 
extension.

 This assumes that all records are always in memory ?

In tmsebufdataset yes.

 The string fields should not necessitate the access of private fields, you
 can just always create TWideStringField instances ?

TWideStringField probably can not handle the MSEgui storage of UnicodeString 
with variable length in datasets.
The code of tmsestringfield:


[...]
function tmsebufdataset.getmsestringdata(const sender: tmsestringfield;
   out avalue: msestring): boolean;
var
 po1: pointer;
 int1: integer;
begin
 {$ifdef FPC}{$warnings off}{$endif}
 with tfieldcracker(sender) do begin
 {$ifdef FPC}{$warnings on}{$endif}
  if fvalidating then begin
   result:= (fvaluebuffer  nil) and (foffset and 1 = 0);
   po1:= fvaluebuffer;
  end
  else begin
   result:= getfieldbuffer(sender,po1,int1);
  end;
 end;
 if result then begin
  avalue:= msestring(po1^);
 end
 else begin
  avalue:= '';
 end;
end;
[...]
{ tmsestringfield }

destructor tmsestringfield.destroy;
begin
 if fdsintf  nil then begin
  fdsintf.fielddestroyed(ifieldcomponent(self));
 end;
 inherited;
end;

function tmsestringfield.HasParent: Boolean;
begin
 result:= dataset  nil;
end;

function tmsestringfield.assql: string;
begin
 result:= fieldtosql(self);
end;

function tmsestringfield.getasmsestring: msestring;
begin
 if assigned(fgetmsestringdata) then begin
  fgetmsestringdata(self,result);
 end
 else begin
  result:= fieldgetmsestring(self,fdsintf);
 end;
end;

procedure tmsestringfield.setasnullmsestring(const avalue: msestring);
begin
 if avalue = '' then begin
  clear;
 end
 else begin
  setasmsestring(avalue);
 end;
end;

procedure tmsestringfield.setasmsestring(const avalue: msestring);
begin
 if assigned(fsetmsestringdata) then begin
  fsetmsestringdata(self,avalue);
 end
 else begin
  fieldsetmsestring(avalue,self,fdsintf);
 end;
end;

procedure tmsestringfield.readlookup(reader: treader);
begin
 reader.readboolean;
end;

procedure tmsestringfield.defineproperties(filer: tfiler);
begin
 inherited;
 filer.defineproperty('Lookup',@readlookup,nil,false);
end;

{$ifdef hasaswidestring}
function tmsestringfield.getaswidestring: widestring;
begin
 result:= asmsestring;
end;

procedure tmsestringfield.setaswidestring(const avalue: widestring);
begin
 asmsestring:= avalue;
end;
{$endif}

procedure tmsestringfield.setdsintf(const avalue: idsfieldcontroller);
begin
 fdsintf:= avalue;
end;

function tmsestringfield.getinstance: tfield;
begin
 result:= self;
end;

procedure tmsestringfield.Clear;
begin
 setdata(nil);
end;

function tmsestringfield.oldmsestring(out aisnull: boolean): msestring;
var
 statebefore: tdatasetstate;
begin
 statebefore:= tdataset1(dataset).settempstate(dsoldvalue);
 aisnull:= not getdata(nil);
 result:= getasmsestring;
 tdataset1(dataset).restorestate(statebefore);
end;

function tmsestringfield.oldmsestring: msestring;
var
 bo1: boolean;
begin
 result:= curmsestring(bo1);
end;

function tmsestringfield.curmsestring(out aisnull: boolean): msestring;
var
 statebefore: tdatasetstate;
begin
 statebefore:= tdataset1(dataset).settempstate(dscurvalue);
 aisnull:= not getdata(nil);
 result:= getasmsestring;
 tdataset1(dataset).restorestate(statebefore);
end;


function tmsestringfield.curmsestring: msestring;
var
 bo1: boolean;
begin
 result:= curmsestring(bo1);
end;

procedure tmsestringfield.setismsestring(const getter: getmsestringdataty;
   const setter: setmsestringdataty; const acharacterlength: integer;
   const aisftwidestring: boolean);
begin
 fcharacterlength:= acharacterlength;
 size:= acharacterlength;
 fgetmsestringdata:= getter;
 fsetmsestringdata:= setter;
 fisftwidestring:= aisftwidestring;
end;

{$ifdef integergetdatasize}
function tmsestringfield.GetDataSize: integer;
{$else}
function tmsestringfield.GetDataSize: Word;
{$endif}
begin
 if assigned(fgetmsestringdata) then begin
  result:= sizeof(msestring);
 end
 else begin
  result:= inherited getdatasize;
 end;
end;

function tmsestringfield.GetAsString: string;
begin
 if assigned(fgetmsestringdata) then begin
  result:= getasmsestring;
 end
 else begin
  result:= inherited getasstring;
 end;
end;

function tmsestringfield.GetAsVariant: variant;
var
 mstr1: msestring;
begin
 if assigned(fgetmsestringdata) then begin
  if fgetmsestringdata(self,mstr1) then begin
   result:= mstr1;
  end
  else begin
   result:= null;
  end;
 end
 else begin
  result:= inherited getasvariant;
 end;
end;

procedure tmsestringfield.SetAsString(const AValue: string);
begin
 if assigned(fsetmsestringdata) then begin
  fsetmsestringdata(self,avalue);
 end
 else begin
  inherited;
 end;
end;


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Mattias Gaertner
On Mon, 16 Jul 2012 16:18:49 +0200
Martin Schreiber mse00...@gmail.com wrote:

 On Monday 16 July 2012 14:08:23 Mattias Gaertner wrote:
  On Mon, 16 Jul 2012 09:35:16 +0200 (CEST)
 
  michael.vancann...@wisa.be wrote:
  [...]
  
TComponent, TWriter, TReader for example because in
MSEide+MSEgui one can place additional components in an inserted tframe
and combination of inherited frames and inherited forms need special
handling.
  
   Basically, you want to drop a component on a Form containing a frame, and
   make it's owner the frame ?
 
  I guess he meant adding a component with
  Owner=Form, Parent=nested frame
  As far as I remember TReader (or TWriter I'm not sure) does not support
  this. Lazarus artificially forbids this too. Internally most code
  supports this.
 
 Correct.
 
  Martin, what do you mean with combination of inherited frames and
  inherited forms need special handling ?
 
 I don't remember exactly and I don't want to remember because of too much 
 headache. ;-)
 Assume frames which had inserted forms (in MSEgui every form or datamodule 
 can 
 act as TFrame, MSEgui has no specific TFrame component), which where 
 inherited and there are descendants which are inserted into a form which 
 possibly has descendants too...

AFAIK inheriting forms with nested frame with nested frame works in
Lazarus. Some years ago I fixed a bug which only appeared at 5
level depth.
TReader/Writer does not know about forms/frames/datamodules, so I guess
it should work for MSE forms too.
MSEGui suppports nesting longer than Lazarus.
Maybe the FCL was fixed in the meantime?

Mattias
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread michael . vancanneyt



On Mon, 16 Jul 2012, Martin Schreiber wrote:


On Monday 16 July 2012 09:35:16 michael.vancann...@wisa.be wrote:



The DB components mainly because MSEgui stores string fields as
UnicodeString in datasets and because of the direct data access by index
without scrolling.


So you take away the concept of cursor. That is a radical change.


The cursor concept still exists, direct access without scrolling is an
extension.


This assumes that all records are always in memory ?


In tmsebufdataset yes.


I will look at what can be done here.




The string fields should not necessitate the access of private fields, you
can just always create TWideStringField instances ?


TWideStringField probably can not handle the MSEgui storage of UnicodeString
with variable length in datasets.
The code of tmsestringfield:


[...]
function tmsebufdataset.getmsestringdata(const sender: tmsestringfield;
  out avalue: msestring): boolean;
var
po1: pointer;
int1: integer;
begin
{$ifdef FPC}{$warnings off}{$endif}
with tfieldcracker(sender) do begin
{$ifdef FPC}{$warnings on}{$endif}
 if fvalidating then begin
  result:= (fvaluebuffer  nil) and (foffset and 1 = 0);


So you need to access to

FValueBuffer : Pointer;
FValidating : Boolean;

I can make these available as protected properties.




Maybe we need a function to decide the class of a string field ?


Probably does not help if the descendant can not access private base fields.


Well, from your code adding the following to the protected section:

  Property ValueBuffer : Pointer Read FValueBuffer;
  Property Validating : Boolean Read FValidating ;

Should be enough to remove the need for the TFieldCracker ?

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Martin Schreiber
On Monday 16 July 2012 16:50:06 michael.vancann...@wisa.be wrote:

 Well, from your code adding the following to the protected section:

Property ValueBuffer : Pointer Read FValueBuffer;
Property Validating : Boolean Read FValidating ;

 Should be enough to remove the need for the TFieldCracker ?

Unfortunately no:

procedure tmsebufdataset.checkfreebuffer(const afield: tfield);
begin
 {$ifdef FPC}{$warnings off}{$endif}
 with tfieldcracker(afield) do begin
 {$ifdef FPC}{$warnings on}{$endif}
  if foffset and 2  0 then begin
   freemem(fvaluebuffer);
   fvaluebuffer:= nil;
  end;
 end;
end;


Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Martin Schreiber
On Monday 16 July 2012 16:49:24 Mattias Gaertner wrote:

 AFAIK inheriting forms with nested frame with nested frame works in
 Lazarus. Some years ago I fixed a bug which only appeared at 5
 level depth.
 TReader/Writer does not know about forms/frames/datamodules, so I guess
 it should work for MSE forms too.
 MSEGui suppports nesting longer than Lazarus.
 Maybe the FCL was fixed in the meantime?

Possible.

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread michael . vancanneyt



On Mon, 16 Jul 2012, Martin Schreiber wrote:


On Monday 16 July 2012 16:50:06 michael.vancann...@wisa.be wrote:


Well, from your code adding the following to the protected section:

   Property ValueBuffer : Pointer Read FValueBuffer;
   Property Validating : Boolean Read FValidating ;

Should be enough to remove the need for the TFieldCracker ?


Unfortunately no:

procedure tmsebufdataset.checkfreebuffer(const afield: tfield);
begin
{$ifdef FPC}{$warnings off}{$endif}
with tfieldcracker(afield) do begin
{$ifdef FPC}{$warnings on}{$endif}
 if foffset and 2  0 then begin
  freemem(fvaluebuffer);
  fvaluebuffer:= nil;
 end;
end;
end;



If I understand correctly, you have in the record buffer just the pointer of
the (wide)string instead of the actual string data ?

If so, why then didn't you implement the string fields as blobs are implemented
in SQLDB (it is basically the same problem), in that case you would not need the 
internal fields of TField at all ?


If that is not possible, it means you need a mechanism to 'finalize' the record 
buffer
whenever it is re-filled or goes out of scope ?

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-16 Thread Martin Schreiber
On Monday 16 July 2012 17:25:58 michael.vancann...@wisa.be wrote:
 On Mon, 16 Jul 2012, Martin Schreiber wrote:
  On Monday 16 July 2012 16:50:06 michael.vancann...@wisa.be wrote:
  Well, from your code adding the following to the protected section:
 
 Property ValueBuffer : Pointer Read FValueBuffer;
 Property Validating : Boolean Read FValidating ;
 
  Should be enough to remove the need for the TFieldCracker ?
 
  Unfortunately no:
  
  procedure tmsebufdataset.checkfreebuffer(const afield: tfield);
  begin
  {$ifdef FPC}{$warnings off}{$endif}
  with tfieldcracker(afield) do begin
  {$ifdef FPC}{$warnings on}{$endif}
   if foffset and 2  0 then begin
freemem(fvaluebuffer);
fvaluebuffer:= nil;
   end;
  end;
  end;
  

 If I understand correctly, you have in the record buffer just the pointer
 of the (wide)string instead of the actual string data ?

Correct. The UnicodeString pointer. That has not directly to do with the 
procedure above BTW. This one is to allow changing field values in OnValidate 
IIRC.

 If so, why then didn't you implement the string fields as blobs are
 implemented in SQLDB (it is basically the same problem), in that case you
 would not need the internal fields of TField at all ?

Maybe, but what about performance? Another complication is the updatebuffer 
with the oldvalues.

 If that is not possible, it means you need a mechanism to 'finalize' the
 record buffer whenever it is re-filled or goes out of scope ?

That mechanism is implemented in tmsebufdataset and does not need 
tfieldcracker IIRC. tmsebufdatset holds a list of record offsets which must 
be finalized.

Thanks, Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Martin Schreiber
On Saturday 14 July 2012 19:55:39 Sven Barth wrote:
 
  I sometimes need cracker classes in MSEide and MSEgui to fix bugs and

 make

  extensinsions for FCL classes in order to access private fields (examples
  TDataset, TParam, TField, TFiler, TReader, TWriter, TComponent).
  Is it guaranteed that the local definitions have the same layout as the
  definition in the FCL unit?

 Do you have current examples where you fixed bugs? Maybe these can be fixed
 at the source which might be better than making them protected (though this
 can still be done for non-bug fields where you need access to certain
 members)

MSEgui must work with current FPC release so sometimes it is necessary to make 
workarounds until the next FPC release with the bugfixes. As soon as possible 
I remove unneeded cracker classes.
I report all FPC bugs I find apart from the compiler crashes by partial 
compile where reproducing is difficult, needs the whole MSEide+MSEgui source 
and fixing probably would need construction of a new unit handling in FPC. 
Bugs which are Delphi compatible are not reported also. ;-)

Currently I need access to the following private FCL class fields because of 
MSEide+MSEgui extensions:

TComponent:
- FComponents
- FComponentState
- FFreeNotifies

TCollection:
- FItemClass

THandlestream:
- FHandle

TMemoryStream:
- FCapacity

TWriter:
- FPropPath
- FAncestors

TReader:
- FStream
- FLoaded

TDatabase:
- FConnected

TField:
- FValidating
- FValueBuffer
- FOffset
- FFieldno

TFielddef:
- FFieldno

TParam:
- FBound

TDataset:
- FDatasources

I hope I didn't forget anything. Suggestion:
For all FCL base classes which are used in different toolkits and which can't 
be forked without breaking precompiled third party components, namely the 
units classes and db, move *all* private fields and methods to protected and 
mark them as Use on your own risk, can be changed everytime! Don't cry 
afterwards..
I can not fork the listed components because of compatibility with third party 
components. On the other had I forked SQLdb completely when the workaround 
burden became too big.

Thanks, Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Sven Barth

On 15.07.2012 08:58, Martin Schreiber wrote:

I report all FPC bugs I find apart from the compiler crashes by partial
compile where reproducing is difficult, needs the whole MSEide+MSEgui source
and fixing probably would need construction of a new unit handling in FPC.


As the compiler sometimes even breaks when partially recompiling itself 
(from within Lazarus for example) you really don't need to report this ;)


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Skybuck Flying

I don't think this is a good idea.

For example while debugging and looking at the memory in raw this would lead 
to confusion.


It's already bad that Delphi adds invisible fields to classes so they cannot 
be simply dumped to disk... (virtual method table pointers ?) this would 
make it even worse.


Bye,
 Skybuck.

-Original Message- 
From: Jonas Maebe

Sent: Saturday, July 14, 2012 1:44
To: fpc-devel@lists.freepascal.org
Subject: [fpc-devel] Class field reordering


Hi,

I've implemented an optimization that reorders the instance fields of
Delphi-style classes (and only of Delphi-style classes) to minimise
memory gaps caused by alignment differences and odd sizes. The effect
is the same as when you would change the order of the fields in the
source code to achieve this effect.

In general, I think this should be safe since unlike records and
TP-style objects, a Delphi class is normally never blockwritten to
disk or so. There is a switch to disable this transformation, but I'm
wondering whether anyone sees a problem with enabling it by default
when -O2 or higher is used.

It works fine with at least the compiler and Lazarus without any ill
effects, saving a small amount of memory for both (about 2.5MB on 87MB
for the Darwin/x86-64 compiler compiling itslf, and 2.5MB on 62.7MB
for a Carbon/i386 Lazarus right after startup and loading some source
files).


Jonas

PS: a similar reordering could be performed for local variables,
although the implementation would be quite different. Additionally,
different kinds of reordering, e.g. targeting cache improvements by
putting fields/local variables often used together next to each other,
could also be implemented in the future.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel 


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Jonas Maebe

On 14 Jul 2012, at 14:16, Skybuck Flying wrote:

 I don't think this is a good idea.
 
 For example while debugging and looking at the memory in raw this would lead 
 to confusion.

By knowing the order of the fields, you still don't know their exact offsets. 
If you want to know their address, print @classinstance.fieldname

 It's already bad that Delphi adds invisible fields to classes so they cannot 
 be simply dumped to disk... (virtual method table pointers ?) this would make 
 it even worse.

If you want to program at an assembler level of abstraction, don't use high 
level language features.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Michael Van Canneyt



On Sat, 14 Jul 2012, Martin Schreiber wrote:


On Saturday 14 July 2012 14:26:32 Michael Van Canneyt wrote:

If would you want to use that optimization, then yes. Working around
the type system of the language is however generally asking for trouble,
regardless of what reason you do it for.


Indeed. Maybe we can help by making some methods/properties protected ?


You are talking seriously? If so I'll provide a list of private FCL fields I
need to access in MSEide+MSEgui.


A class model is not good if you continuously need to hack your way around it.
That is not to say that I will agree with all you ask, of course.

But please give reasons why you think you need to access these fields.
Maybe we can, in some cases, find alternatives to solve your problem(s).

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Michael Van Canneyt



On Sun, 15 Jul 2012, Martin Schreiber wrote:


Currently I need access to the following private FCL class fields because of
MSEide+MSEgui extensions:


I have looked at your list. (I sent my previous mail about this without having 
seen the list)


At first sight, I see no reason to make any of these fields protected.

For example:
TParam.FBound
Is directly accessible through TParam.Bound, so why on earth would you need to 
have it protected ??

Can you give some explanations at least of what you're trying to do, 
maybe we can find workarounds for your problems ?


Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Graeme Geldenhuys
Hi,

On 15 July 2012 18:21, Michael Van Canneyt mich...@freepascal.org wrote:
 For example:
 TParam.FBound
 Is directly accessible through TParam.Bound, so why on earth would you need
 to have it protected ??


I haven't worked through his list myself, but I had a quick look at
one property I had issues with ages ago ComponentState is a
read-only property and FComponentState is private. Originally I
couldn't set csLoading because of the private field variable, but
luckily the FPC team was accommodating by adding a protected virtual
Loading() method so that I could set/unset the property. They could
have just made ComponentState read-write too, but didn't for some
reason. Now Delphi and Lazarus never needed this for some reason due
to TWriter/TReader being in the same unit (or something like that),
but fpGUI doesn't because its loading of forms work very differently.

Anyway, I'm not saying I agree with his whole list... as your example
shows, TParam.Bound is a public read-write property already... my
example of ComponentState wasn't, but I only needed csLoading. Maybe
Martin needs to set some of the other states too and no related
methods exist?

Anyway, as you said, maybe justifying some of those items in his list
could hep explain the problems more - and suitable solutions could be
found.


-- 
Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://fpgui.sourceforge.net
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Michael Van Canneyt



On Sun, 15 Jul 2012, Graeme Geldenhuys wrote:


Hi,

On 15 July 2012 18:21, Michael Van Canneyt mich...@freepascal.org wrote:

For example:
TParam.FBound
Is directly accessible through TParam.Bound, so why on earth would you need
to have it protected ??



Anyway, I'm not saying I agree with his whole list... as your example
shows, TParam.Bound is a public read-write property already... my
example of ComponentState wasn't, but I only needed csLoading. Maybe
Martin needs to set some of the other states too and no related
methods exist?

Anyway, as you said, maybe justifying some of those items in his list
could hep explain the problems more - and suitable solutions could be
found.


Well, hopefully, yes.

Usually these things are private for a reason. But maybe there 
are better reasons for doing it different, of course then I'd 
like to hear them first :)


Changing them without any justification whatsoever is definitely not going 
to happen.


Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Martin Schreiber
On Sunday 15 July 2012 19:21:58 Michael Van Canneyt wrote:
 On Sun, 15 Jul 2012, Martin Schreiber wrote:
  Currently I need access to the following private FCL class fields because
  of MSEide+MSEgui extensions:

 I have looked at your list. (I sent my previous mail about this without
 having seen the list)

 At first sight, I see no reason to make any of these fields protected.

Jup, I feared it. ;-)

 For example:
 TParam.FBound
 Is directly accessible through TParam.Bound, so why on earth would you need
 to have it protected ??

Hmm, this probably is a mistake from me. Was it writeable in all FPC versions?

 Can you give some explanations at least of what you're trying to do,
 maybe we can find workarounds for your problems ?

Before I started to use cracker classes I searched workarounds for weeks or 
even months already...
If you want you can grep the MSEide+MSEgui sources for cracker in order see 
what I do with them. TComponent, TWriter, TReader for example because in 
MSEide+MSEgui one can place additional components in an inserted tframe and 
combination of inherited frames and inherited forms need special handling. 
The DB components mainly because MSEgui stores string fields as UnicodeString 
in datasets and because of the direct data access by index without scrolling. 
The stream components because in MSEgui there is a single hierarchy for file 
and memory stream so the more specialized descendants (ttextstream, 
ttextdatastream) can work on files and on memory.

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Graeme Geldenhuys
On 15 July 2012 19:04, Michael Van Canneyt mich...@freepascal.org wrote:
 Usually these things are private for a reason. But maybe there are better
 reasons for doing it different, of course then I'd like to hear them first
 :)

Yes, and I just wanted to point out that I some time ago I showed a
case where I needed to set ComponentState manually but couldn't... The
FPC team can't cover all possible use cases. Not everybody is creating
a Delphi clone application or framework, so there could very possibly
be a valid reason for doing something different to Delphi or Lazarus.


 Changing them without any justification whatsoever is definitely not going
 to happen.

I fully agree.


-- 
Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://fpgui.sourceforge.net
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-15 Thread Hans-Peter Diettrich

Graeme Geldenhuys schrieb:

On 15 July 2012 19:04, Michael Van Canneyt mich...@freepascal.org wrote:

Usually these things are private for a reason. But maybe there are better
reasons for doing it different, of course then I'd like to hear them first
:)


Yes, and I just wanted to point out that I some time ago I showed a
case where I needed to set ComponentState manually but couldn't... The
FPC team can't cover all possible use cases. Not everybody is creating
a Delphi clone application or framework, so there could very possibly
be a valid reason for doing something different to Delphi or Lazarus.


IMO it's a matter of component users vs. writers. A component writer 
needs write access to some properties, which a user only should read. 
The base class designers do not always see such needs, when they 
implement everything in a single unit with lower protection boundaries. 
Some members of TControl and TWinControl should be protected, not 
private, and such a move won't change anything in user land.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Jonas Maebe

On 14 Jul 2012, at 08:00, Martin Schreiber wrote:

 On Saturday 14 July 2012 07:50:58 Martin Schreiber wrote:
 On Saturday 14 July 2012 01:44:39 Jonas Maebe wrote:
 I've implemented an optimization that reorders the instance fields of
 Delphi-style classes (and only of Delphi-style classes) to minimise
 memory gaps caused by alignment differences and odd sizes. The effect
 is the same as when you would change the order of the fields in the
 source code to achieve this effect.
 
 I sometimes need cracker classes in MSEide and MSEgui to fix bugs and
 make extensinsions for FCL classes in order to access private fields
 (examples TDataset, TParam, TField, TFiler, TReader, TWriter, TComponent).
 Is it guaranteed that the local definitions have the same layout as the
 definition in the FCL unit?

If you you use the same packrecords setting, yes (I doubt any such fcl units 
contain packrecords directives though, in which case they'll use the default).

 Hmm, up to now I listed in the cracker classes fields up to the last private 
 field I need to access so the cracker classes would not brake by changing or 
 adding successive fields in the original classes. I assume now it is 
 necessary to always list all fields of the original class.

If would you want to use that optimization, then yes. Working around the type 
system of the language is however generally asking for trouble, regardless of 
what reason you do it for.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Michael Van Canneyt



On Sat, 14 Jul 2012, Jonas Maebe wrote:



On 14 Jul 2012, at 08:00, Martin Schreiber wrote:


On Saturday 14 July 2012 07:50:58 Martin Schreiber wrote:

On Saturday 14 July 2012 01:44:39 Jonas Maebe wrote:

I've implemented an optimization that reorders the instance fields of
Delphi-style classes (and only of Delphi-style classes) to minimise
memory gaps caused by alignment differences and odd sizes. The effect
is the same as when you would change the order of the fields in the
source code to achieve this effect.


I sometimes need cracker classes in MSEide and MSEgui to fix bugs and
make extensinsions for FCL classes in order to access private fields
(examples TDataset, TParam, TField, TFiler, TReader, TWriter, TComponent).
Is it guaranteed that the local definitions have the same layout as the
definition in the FCL unit?


If you you use the same packrecords setting, yes (I doubt any such fcl units 
contain packrecords directives though, in which case they'll use the default).


Hmm, up to now I listed in the cracker classes fields up to the last private
field I need to access so the cracker classes would not brake by changing or
adding successive fields in the original classes. I assume now it is
necessary to always list all fields of the original class.


If would you want to use that optimization, then yes. Working around the
type system of the language is however generally asking for trouble,
regardless of what reason you do it for.


Indeed. Maybe we can help by making some methods/properties protected ?

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Martin Schreiber
On Saturday 14 July 2012 14:26:32 Michael Van Canneyt wrote:
  If would you want to use that optimization, then yes. Working around
  the type system of the language is however generally asking for trouble,
  regardless of what reason you do it for.

 Indeed. Maybe we can help by making some methods/properties protected ?

You are talking seriously? If so I'll provide a list of private FCL fields I 
need to access in MSEide+MSEgui.

Thanks Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Martin Schreiber
On Saturday 14 July 2012 14:07:30 Jonas Maebe wrote:

  Hmm, up to now I listed in the cracker classes fields up to the last
  private field I need to access so the cracker classes would not brake by
  changing or adding successive fields in the original classes. I assume
  now it is necessary to always list all fields of the original class.

 If would you want to use that optimization, then yes. Working around the
 type system of the language is however generally asking for trouble,
 regardless of what reason you do it for.

I do not necessarily want to use field order optimization but if the FPC RTL 
is compiled with it I need to compile my cracker classes with optimization 
too.

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Sven Barth
Am 14.07.2012 07:45 schrieb Martin Schreiber mse00...@gmail.com:

 On Saturday 14 July 2012 01:44:39 Jonas Maebe wrote:
  Hi,
 
  I've implemented an optimization that reorders the instance fields of
  Delphi-style classes (and only of Delphi-style classes) to minimise
  memory gaps caused by alignment differences and odd sizes. The effect
  is the same as when you would change the order of the fields in the
  source code to achieve this effect.
 
 I sometimes need cracker classes in MSEide and MSEgui to fix bugs and
make
 extensinsions for FCL classes in order to access private fields (examples
 TDataset, TParam, TField, TFiler, TReader, TWriter, TComponent).
 Is it guaranteed that the local definitions have the same layout as the
 definition in the FCL unit?

Do you have current examples where you fixed bugs? Maybe these can be fixed
at the source which might be better than making them protected (though this
can still be done for non-bug fields where you need access to certain
members)

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Florian Klämpfl
Am 14.07.2012 01:44, schrieb Jonas Maebe:
 
 Hi,
 
 I've implemented an optimization that reorders the instance fields of
 Delphi-style classes (and only of Delphi-style classes) to minimise
 memory gaps caused by alignment differences and odd sizes. The effect is
 the same as when you would change the order of the fields in the source
 code to achieve this effect.
 
 In general, I think this should be safe since unlike records and
 TP-style objects, a Delphi class is normally never blockwritten to disk
 or so. There is a switch to disable this transformation, but I'm
 wondering whether anyone sees a problem with enabling it by default when
 -O2 or higher is used.

The only drawback I see that people might sort fields for better cache
usage but this is rarely the case imo. So if the optimization can be
turned off, it should be fine.

 
 It works fine with at least the compiler and Lazarus without any ill
 effects, saving a small amount of memory for both (about 2.5MB on 87MB
 for the Darwin/x86-64 compiler compiling itslf, and 2.5MB on 62.7MB for
 a Carbon/i386 Lazarus right after startup and loading some source files).
 
 
 Jonas
 
 PS: a similar reordering could be performed for local variables,
 although the implementation would be quite different. Additionally,
 different kinds of reordering, e.g. targeting cache improvements by
 putting fields/local variables often used together next to each other,
 could also be implemented in the future.
 ___
 fpc-devel maillist  -  fpc-devel@lists.freepascal.org
 http://lists.freepascal.org/mailman/listinfo/fpc-devel
 


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Nico Erfurth
On 14.07.12 01:44, Jonas Maebe wrote:

 I've implemented an optimization that reorders the instance fields of
 Delphi-style classes (and only of Delphi-style classes) to minimise
 memory gaps caused by alignment differences and odd sizes. The effect is
 the same as when you would change the order of the fields in the source
 code to achieve this effect.
 
 In general, I think this should be safe since unlike records and
 TP-style objects, a Delphi class is normally never blockwritten to disk
 or so. There is a switch to disable this transformation, but I'm
 wondering whether anyone sees a problem with enabling it by default when
 -O2 or higher is used.

As this might cause an overall gain by better cache utilization i would
keep it on by default. But I think it would be best that it can be
disabled per class-definition. If somebody tries to do manual cache
optimization it will usually only be for a couple of classes. Not the
whole project.

So basically, something like

class MyClass = class
{$OPTIMIZATION OFF}
  private
FHeavilyUsedValue: Boolean;
FAlsoHeavilyUsedValue: DWord;
{$OPTIMIZATION DEFAULT}
NotOftenUsed: Byte;
end;

should leave the ordering of the first values alone, while optimizing
the rest. Or at least disable reordering for the whole class.

Nico
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Jonas Maebe

On 14 Jul 2012, at 18:02, Martin Schreiber wrote:

 I do not necessarily want to use field order optimization but if the FPC RTL 
 is compiled with it I need to compile my cracker classes with optimization 
 too.

That's indeed true.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Jonas Maebe

On 14 Jul 2012, at 20:29, Nico Erfurth wrote:

 So basically, something like
 
 class MyClass = class
 {$OPTIMIZATION OFF}
  private
FHeavilyUsedValue: Boolean;
FAlsoHeavilyUsedValue: DWord;
 {$OPTIMIZATION DEFAULT}
NotOftenUsed: Byte;
 end;
 
 should leave the ordering of the first values alone, while optimizing
 the rest. Or at least disable reordering for the whole class.

Only the setting active at the end of the class declaration (before the end) 
will have effect. The setting can be changed via {$optimization orderfields} 
and {$optimization noorderfields}, just like all other optimization settings.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Jonas Maebe

On 14 Jul 2012, at 20:52, Jonas Maebe wrote:

 On 14 Jul 2012, at 18:02, Martin Schreiber wrote:
 
 I do not necessarily want to use field order optimization but if the FPC RTL 
 is compiled with it I need to compile my cracker classes with optimization 
 too.
 
 That's indeed true.

That may actually lead to quite some troubles: if someone recompiles the RTL 
without optimizations, then your class crackers also have to change that 
setting. And there's no way to detect how the RTL (or in general: units 
containing classes you are cracking) has been compiled in your source code. 
Adding support for something like that is definitely not a road I want to go 
down -- even a switch to simply treat all private fields as protected would 
be less bad (not that I would consider such a switch desirable in any way; it's 
like adding a switch to allow calling functions only declared in the 
implementation of another unit).

On the other hand, regardless of whether or not we would make that 
transformation the default for the release units, you will always get problems 
if someone recompiles the FPC units using the opposite setting. So that's 
mainly an argument against including this feature altogether in the compiler, 
at least without additional hacks to make class crackers a sort of supported 
feature one way or another (which I would be quite reluctant to do).

This demonstrates a real pain of low level languages: there's almost always at 
least one way in which someone has figured out a way to break the language, 
killing a lot of possible optimizations and error checking you would normally 
be able to do without any problem, unless you want to go through the trouble of 
annoying at least some users (or, in cases like this one, adding extra 
complexity to turn that breakage into a supported feature).

I once had a discussion with a person who worked on IBM's C compiler, and he 
said they couldn't even reorder local variables that do not fit in a register 
because certain large commercial code bases they had to be able to compile 
correctly explicitly relied on buffer overflows from one local variable into 
the next according to the source declaration order (and annoying those users 
was not an option).

I guess there are probably no such FPC-compiled programs yet (*), so maybe now 
is the time to add that before we also get stuck with that particular piece of 
ballast.


Jonas

(*) except for a few in the FPC testsuite whose purpose is to verify that 
certain code in fact does not cause a buffer overflow; but those can be easily 
changed to use all variables of the same size to prevent 
reordering___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-14 Thread Sven Barth
Am 14.07.2012 21:48 schrieb Jonas Maebe jonas.ma...@elis.ugent.be:
 I guess there are probably no such FPC-compiled programs yet (*), so
maybe now is the time to add that before we also get stuck with that
particular piece of ballast.

Somehow I have the feeling that we all know what one of your upcoming
commits will be :P

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-13 Thread Craig Peterson


On Jul 13, 2012, at 6:44 PM, Jonas Maebe jonas.ma...@elis.ugent.be wrote:

 
 Hi,
 
 I've implemented an optimization that reorders the instance fields of 
 Delphi-style classes (and only of Delphi-style classes) to minimise memory 
 gaps caused by alignment differences and odd sizes. The effect is the same as 
 when you would change the order of the fields in the source code to achieve 
 this effect.
 
 In general, I think this should be safe since unlike records and TP-style 
 objects, a Delphi class is normally never blockwritten to disk or so. There 
 is a switch to disable this transformation, but I'm wondering whether anyone 
 sees a problem with enabling it by default when -O2 or higher is used.
 
 It works fine with at least the compiler and Lazarus without any ill effects, 
 saving a small amount of memory for both (about 2.5MB on 87MB for the 
 Darwin/x86-64 compiler compiling itslf, and 2.5MB on 62.7MB for a Carbon/i386 
 Lazarus right after startup and loading some source files).
 
 
 Jonas
 
 PS: a similar reordering could be performed for local variables, although the 
 implementation would be quite different. Additionally, different kinds of 
 reordering, e.g. targeting cache improvements by putting fields/local 
 variables often used together next to each other, could also be implemented 
 in the future.
 ___
 fpc-devel maillist  -  fpc-devel@lists.freepascal.org
 http://lists.freepascal.org/mailman/listinfo/fpc-devel

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-13 Thread Martin Schreiber
On Saturday 14 July 2012 01:44:39 Jonas Maebe wrote:
 Hi,

 I've implemented an optimization that reorders the instance fields of
 Delphi-style classes (and only of Delphi-style classes) to minimise
 memory gaps caused by alignment differences and odd sizes. The effect
 is the same as when you would change the order of the fields in the
 source code to achieve this effect.

I sometimes need cracker classes in MSEide and MSEgui to fix bugs and make 
extensinsions for FCL classes in order to access private fields (examples 
TDataset, TParam, TField, TFiler, TReader, TWriter, TComponent).
Is it guaranteed that the local definitions have the same layout as the 
definition in the FCL unit?

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Class field reordering

2012-07-13 Thread Martin Schreiber
On Saturday 14 July 2012 07:50:58 Martin Schreiber wrote:
 On Saturday 14 July 2012 01:44:39 Jonas Maebe wrote:
  Hi,
 
  I've implemented an optimization that reorders the instance fields of
  Delphi-style classes (and only of Delphi-style classes) to minimise
  memory gaps caused by alignment differences and odd sizes. The effect
  is the same as when you would change the order of the fields in the
  source code to achieve this effect.

 I sometimes need cracker classes in MSEide and MSEgui to fix bugs and
 make extensinsions for FCL classes in order to access private fields
 (examples TDataset, TParam, TField, TFiler, TReader, TWriter, TComponent).
 Is it guaranteed that the local definitions have the same layout as the
 definition in the FCL unit?

Hmm, up to now I listed in the cracker classes fields up to the last private 
field I need to access so the cracker classes would not brake by changing or 
adding successive fields in the original classes. I assume now it is 
necessary to always list all fields of the original class.

Martin


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel