Sven Jauring wrote:
Recently I posted some questions concerning problems with 16 bit sets. I got good suggestions from some of you, but further analysis of the code revealed this kind of construct:
TYPE INT16 = INTEGER(16); INT8 = packed 0.. INT0_65535 = packed 0..65535; B_TYPE = (B1, B2, B3, B4, B5, B6, B7, B8); BITS = (BIT0,BIT1,BIT2,BIT3,BIT4,BIT5,BIT6,BIT7,BIT8,BIT9,
BIT10,BIT11,BIT12,BIT13,BIT14,BIT15); B_TYPE_SET = set of B_TYPE; BIT_SET = set of BITS;
VAR OUT_REC = record case INT16 of 0 : (BSLB: B_TYPE_SET; BSHB: B_TYPE_SET); 1 : (USRINT : INT0_65535); 2 : (BT: BIT_SET); END;
The code heavily depends on the record variants to be aligned exactly on top of each other.
Is there anyone in the GPC project that is working, or planning to work,
on this issue? ("optimized set constructor"??) How long would it take? The company I'm working for, HiQ Approve AB, is willing to discuss a financial contribution to get this done.
I haven't followed the thread too intensely since I was out of town last week. If I understand it correctly, what you need is that a set of a type of, say 8, elements is only 1 byte large. (However, in the code above, there will also be endianness problems, i.e. on a little-endian system BSLB would align with the least significant bits of USRINT and on a big-endian system with the most significant bits; this problem could be overcome with a conditional compilation, see, e.g., the declaration of TWindowXY in GPC's CRT unit).
GPC internally stores sets as arrays of a certain type, currently MedCard. It is fairly easy to change that type to Byte (requires a small change in p/rts/sets.pas (TSelElement) and two in p/util.c (set_word_size and set_alignment)).
However note:
- This will slightly decrease the performance of set routines since they will use byte rather than word operations internally.
- Sets with and without this change will be incompatible. Don't try to mix object files created by a patched and an unpatched compiler.
- This works only down to bytes. Trying even smaller types (like Cardinal (4)) there will not work.
Another approach would be to keep the array of words for sets at least as big as a word, and use a single smaller type for smaller sets. Then they would take only as many bits as required within a packed record. However, this would require quite some effort. Basically, every set operation would have to check if their arguemnts are of the second type and convert them, and likewise convert back the result.
Personally, I'd suggest to change your Pascal code to not rely on the variant alignment and such ...
Frank