On Oct 22, 09 17:31, AJ wrote:
"Nick Sabalausky"<a...@a.a> wrote in message
news:hboui3$1bb...@digitalmars.com...
"AJ"<a...@nospam.net> wrote in message
news:hbor97$155...@digitalmars.com...
"Nick Sabalausky"<a...@a.a> wrote in message
news:hbonj3$u3...@digitalmars.com...
"AJ"<a...@nospam.net> wrote in message
news:hboa9p$5m...@digitalmars.com...
How do you make ABC below work on a platform that requires 32-bit
integers to be aligned on 32-bit boundaries while keeping the layount
and size of ABC the same as on a platform that has no such alignment
requirement?
struct ABC
{
byte a;
int b; // may be improperly aligned on some platforms
int64 c; // same issue
};
It can be done by using bitmasks and bit shifting on every access.
I had a feeling I was delving into "dangerous territory" (read, way too
low level for me, but I wonder what the possibilities are). I have a
feeling that I may be wanting hardware standardization because it can't
be "solved" at the language level (?).
I don't understand how using bitmasks and bit shifting on every access
would work
Normally, the compiler would turn this:
myabc1.b = myabc2.b + 1;
Into something like this:
- move value at memory address xxxxx (myabc2.b) into cpu register
- add 1
- move value in cpu register into memory address xxxxx (myabc1.b)
If the compiler knows that myabc1.b and myabc2.b are not aligned in a way
that the cpu can directly access, then what it would turn it into is
something like:
- move the values at the two memory addresses that myabc2.b straddles into
cpu registers
- use bit manipulation tricks to throw away myabc2.a and myabc2.c and
compine the two parts of myabc2.b
- add 1
- use bit manipulation tricks to split the value in the cpu register back
into two parts, and mix in myabc1.a and myabc1.c
- move the restulting values into the memory addresses that myabc1.b
straddles
OK, thanks.
the plausibility of it
It should always possible. Although references to the struct's members
would probably be very tricky and require a lot of extra fancy work.
I should have used 'practicality' instead of 'plausibility'. So maybe not so
practical (unless the concept is a real boon). (No, I don't know what a
"boon" is either ;) ).
and the cost (in execution time) of doing so.
Depends completely on the cpu, of course. In general though, it's quite a
bit slower (a single fetch or store turns into at least two fetches/stores
plus some bitmasking and shifting, maybe uses up extra registers, and
would make less of the code fit in cache). But that's the price you pay
for using packed structs like that on such a CPU. Or you could just use
align(4) to guarantee 32-bit alignment on all fields for all cpus.
Yes, surely that is the way to go. Or... craft structs to align nicely in
the first place and make the decision on which CPUs you want one set of code
to run on:
struct ABC
{
byte a;
byte pad1;
byte pad2;
byte pad3;
int b; // may be improperly aligned on some platforms
int64 c; // same issue
}
If data offset is really that important, you should use a bitfield.