comp.lang.ada
 help / color / mirror / Atom feed
* Re: Representation clauses and records
       [not found] <347000b1.4909762@news.geccs.gecm.com>
@ 1997-11-21  0:00 ` Brian Nettleton
  1997-11-21  0:00   ` Matthew Heaney
                     ` (2 more replies)
  1997-12-16  0:00 ` Pascal MALAISE
  1 sibling, 3 replies; 13+ messages in thread
From: Brian Nettleton @ 1997-11-21  0:00 UTC (permalink / raw)
  To: brian.orpin


Brian Orpin wrote:

> I have played with this before but never fully understood it.  Now I need
> to understand it and my colleagues and I have had many hours discussing
> it.  The compiler being used is Ada 83.
>
> The question is simple; when declaring a representation clause for a
> record there is an optional alignment clause using 'mod at'.  What effect
> does this have on the component representation clause and how does this
> relate to the storage size of the system?
>
> Having read the LRM I get the impression that it is to do with word
> boundaries and alignment but I do not understand the implications of
> using different values for the 'at mod' statement.
>
> Any explanations gratefully received.  This is not homework :-))
>
> --
> Brian Orpin    (These thoughts are my own ......... for once!)
> brian.orpin@ge_XXX_cm.com or BrianOrpin@Big_XXX_foot.com
> http://www.borpin.demon.co.uk/  **Anti-spam reply-to remove X**

Alignment is an important consideration for the representation of data
items at the hardware level.  Many (most?) hardware
architectures/implementations
(ie. Intel Pentium, PowerPC, SPARC, etc.) have performance penalties
associated with mis-aligned data items.  Loading a word into a register
for a mis-aligned address usually involves either extra instructions or extra

hardware cycles.  This means that there are different space/time tradeoffs
for
different alignments.  Consider (simple example with 32 bit word assumption):

  type Space_Optimized_Array_Element is record
    Field1 : Integer;
    Field2 : Boolean;
  end record;

  for Space_Optimized_Array_Element use record
    at mod 1;
    Field1 at 0 range 0 .. 31;
    Field2 at 4 range 0 .. 8;
  end record;

  type Space_Optimized_Array_Type is array (1..2) of
Space_Optimized_Array_Element;
  pragma Pack(Space_Optimized_Array); -- Ada83 method to assure space opt.

  Space_Optimized_Array : Space_Optimized_Array_Type;

And:

  type Time_Optimized_Array_Element is record
    Field1 : Integer;
    Field2 : Boolean;
  end record;

  for Time_Optimized_Array_Element use record
    at mod 4;
    Field1 at 0 range 0 .. 31;
    Field2 at 4 range 0 .. 8;
  end record;

  type Time_Optimized_Array_Type is array (1..2) of
Time_Optimized_Array_Element;

  Time_Optimized_Array : Time_Optimized_Array_Type;


Layout of Space_Optimized_Array and Time_Optimized_Array:

Offset (in bytes)        Data Item
----------------        ----------
0                               Space_Optimized_Array(1).Field1
4                               Space_Optimized_Array(1).Field2
5 --misaligned           Space_Optimized_Array(2).Field1
9                               Space_Optimized_Array(2).Field2

0                                Time_Optimized_Array(1).Field1
4                                Time_Optimized_Array(1).Field2
8 --aligned                 Time_Optimized_Array(2).Field1
12                              Time_Optimized_Array(2).Field2


Now the Space_Optimized_Array should be 10 bytes in length and accessing
Field1 may take more CPU cycles, and Time_Optimized_Array is generally 16
bytes in length, but accesses to Field1 should always take a minimum number
of CPU cycles.

-Brian Nettleton
Aonix






^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-11-21  0:00 ` Representation clauses and records Brian Nettleton
@ 1997-11-21  0:00   ` Matthew Heaney
  1997-11-21  0:00   ` Brian Nettleton
       [not found]   ` <347a8dc3.3438484@news.geccs.gecm.com>
  2 siblings, 0 replies; 13+ messages in thread
From: Matthew Heaney @ 1997-11-21  0:00 UTC (permalink / raw)




>Brian Orpin wrote:
>
>> I have played with this before but never fully understood it.  Now I need
>> to understand it and my colleagues and I have had many hours discussing
>> it.  The compiler being used is Ada 83.
>>
>> The question is simple; when declaring a representation clause for a
>> record there is an optional alignment clause using 'mod at'. 

FYI (I know you said you're using Ada 83):

Just to let you know: the mod clause you refer to is an obselescent feature
of the language (see RM95 J.8).  It was replaced by an "alignment clause."

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-11-21  0:00 ` Representation clauses and records Brian Nettleton
  1997-11-21  0:00   ` Matthew Heaney
@ 1997-11-21  0:00   ` Brian Nettleton
  1997-11-24  0:00     ` Martin M Dowie
       [not found]   ` <347a8dc3.3438484@news.geccs.gecm.com>
  2 siblings, 1 reply; 13+ messages in thread
From: Brian Nettleton @ 1997-11-21  0:00 UTC (permalink / raw)



Oops, my example has an error.

Brian Nettleton wrote:

>   for Space_Optimized_Array_Element use record
>     at mod 1;
>     Field1 at 0 range 0 .. 31;

>     Field2 at 4 range 0 .. 8;

Should be "Field2 at 4 range 0 .. 7;"

>   end record;
>
>   type Space_Optimized_Array_Type is array (1..2) of
> Space_Optimized_Array_Element;
>   pragma Pack(Space_Optimized_Array); -- Ada83 method to assure space opt.
>
>   Space_Optimized_Array : Space_Optimized_Array_Type;
>
> And:
>
>   type Time_Optimized_Array_Element is record
>     Field1 : Integer;
>     Field2 : Boolean;
>   end record;
>
>   for Time_Optimized_Array_Element use record
>     at mod 4;
>     Field1 at 0 range 0 .. 31;
>     Field2 at 4 range 0 .. 8;

And again "Field2 at 4 range 0 .. 7;"



-Brian Nettleton





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-11-21  0:00   ` Brian Nettleton
@ 1997-11-24  0:00     ` Martin M Dowie
  1997-11-25  0:00       ` Robert Dewar
  0 siblings, 1 reply; 13+ messages in thread
From: Martin M Dowie @ 1997-11-24  0:00 UTC (permalink / raw)



In article <3475F2DF.80B1E349@aonix.com>, Brian Nettleton <bn@aonix.com>
writes
>>   type Space_Optimized_Array_Type is array (1..2) of
>> Space_Optimized_Array_Element;
>>   pragma Pack(Space_Optimized_Array); -- Ada83 method to assure space opt.

also, from what i remember, there is no obligation on a compiler vendor
to actual 'do' anything with a predefinde pragma other than recognise
it. why not 'for space_optimized_array_type'size use space_optimised_arr
ay_element'storage_size'?..

-- 
Martin M Dowie




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
       [not found]   ` <347a8dc3.3438484@news.geccs.gecm.com>
@ 1997-11-25  0:00     ` Matthew Heaney
  0 siblings, 0 replies; 13+ messages in thread
From: Matthew Heaney @ 1997-11-25  0:00 UTC (permalink / raw)



In article <347a8dc3.3438484@news.geccs.gecm.com>, brian.orpin@gecm.dot.com
wrote:


>So the 'mod at' is forcing the compiler to align each of the records on a
>longword boundary.  I hadn't considered the effect of putting those
>elements in an array :-(.  Does mod 4 always align on longword and is mod
>1 always a byte boundary?  

That's what at mod 4 does: align on a longword boundary; that's the
definition.  What else could it do?

I'm not sure at mod 1 does anything - it's the same as not specifying a mod
clause at all.

>
>If you use mod 1 does the compiler not get confused with a 0..31 rep
>clause?  

mod 1 and 0 .. 31 are different things.  All the mod is doing is stating a
characteristic of the address of a 4 byte object (that it can be any
address, because any address divided by 1 is the itself).  The range part
of the rep clause is stating the location of a component within the object
- relative to the start of the object.


>type Byte is Integer range 0..255;

This is incorrect: I think you meant

type Byte is range 0 .. 255;

But why not use type Interfaces.Unsigned_8?

>for type Byte'Size use 8;
>
>type Four_Bytes is
>record
>        byte_one : byte;
>        byte_two : byte;
>        byte_three : byte;
>        byte_four : byte;
>end record;
>
>then use either
>
>for Four_Bytes use record
>at mod 1
>        byte_one at 0 range 0..7;
>        byte_two at 1 range 0..7;
>        byte_three at 2 range 0..7;
>        byte_four at 3 range 0..7;
>end record;
>
>for Four_Bytes use record
>at mod 4
>        byte_one at 0 range 0..7;
>        byte_two at 0 range 8..15;
>        byte_three at 0 range 16..23;
>        byte_four at 0 range 24..31;
>end record;

This is confused.  Never use mod 1.  And besides, it has nothing to do with
the rest of the rep clause.

What do you require: that objects of the type be aligned on a four-byte
boundary?  If so, then say at mod 4.  Do you have no alignment
requirements?  If so, then say nothing.

If you want to place each component of the record at successive bytes, then
either rep clause above will do.  The rep clause states where each byte
component is relative to the start of the record, but this is different
from the mod clause, which aligns the entire record.

>Am I right in thinking that both these examples are valid and there is no
>real difference between them for a 32 bit system.  The mapping of the
>bytes onto memory is important.

The examples are only different wrt the mod clause - the rep clauses are
equivalent.

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-11-24  0:00     ` Martin M Dowie
@ 1997-11-25  0:00       ` Robert Dewar
  1997-11-27  0:00         ` Martin M Dowie
  0 siblings, 1 reply; 13+ messages in thread
From: Robert Dewar @ 1997-11-25  0:00 UTC (permalink / raw)



Martin says

<<also, from what i remember, there is no obligation on a compiler vendor
to actual 'do' anything with a predefinde pragma other than recognise
it. why not 'for space_optimized_array_type'size use space_optimised_arr
ay_element'storage_size'?..
>>

No, you remember wrong (or perhaps you are trying to remember Ada 83). In
Ada 95, if annex C is supported, pragma Pack very definitely cannot be
ignored. The exact rules for what it must support are clear in the RM.

There is some implementation dependence, to be sure. For example, packing
2 bit quantities must be tight, but packing 3 bit quantities can either
be tight, or use 4 bits/element on a typical machine.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-11-25  0:00       ` Robert Dewar
@ 1997-11-27  0:00         ` Martin M Dowie
  0 siblings, 0 replies; 13+ messages in thread
From: Martin M Dowie @ 1997-11-27  0:00 UTC (permalink / raw)



In article <dewar.880513952@merv>, Robert Dewar <dewar@merv.cs.nyu.edu>
writes
>No, you remember wrong (or perhaps you are trying to remember Ada 83).

the previous article was on Ada83 - my fault for cutting off too much
from it - but thanks for the '95 tip! ;-)

-- 
Martin M Dowie




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
       [not found] <347000b1.4909762@news.geccs.gecm.com>
  1997-11-21  0:00 ` Representation clauses and records Brian Nettleton
@ 1997-12-16  0:00 ` Pascal MALAISE
  1997-12-16  0:00   ` Larry Kilgallen
  1 sibling, 1 reply; 13+ messages in thread
From: Pascal MALAISE @ 1997-12-16  0:00 UTC (permalink / raw)



Brian Orpin wrote:

> The question is simple; when declaring a representation clause for a
> record there is an optional alignment clause using 'mod at'.  What effect
> does this have on the component representation clause and how does this
> relate to the storage size of the system?
> 
> Having read the LRM I get the impression that it is to do with word
> boundaries and alignment but I do not understand the implications of
> using different values for the 'at mod' statement.

Hope you know a little bit about C, this will help, but anyway.

You expect to receive a message of max 100 bytes.
You declare a buffer of 100 characters.
You call whatever procedure to fill your buffer with the message.
You discover that the beginning of the message is, in fact, an int.
You use any C pointer cast or ADA unchecked conversion to "map" these
first four bytes to an integer.

In C or ADA, you are likely to get a bus error or an unaligned access,
more or less recovered by the operating system or your application :-(

This is because processors make assumptions about the addresses of given
data types:
character/byte - any address
16 bits "word" - address is a multiple of 2
32 bits "int"  - address is is a multiple of 4
64 bits "long" - address is a multiple of 8

When you declare your array of bytes/characaters, the compiler
implements
the array starting at any address. When you cast, the compiler will
consider the new (integer) data as aligned and the processor will trap.

In C, the workaroud is to always define arrays of longs (64 bits) of
the according size.
In ADA, you can specify an alignment clause for your buffer/structure.

Note that, however, compilers are intelligent:
when you define a record or even a "union", the fields are implemented
(alignment of first field + gaps for the others) to match the
alignment requirements of each field. So, as long as you don't "cast"
it should be OK.


-- 
Pascal MALAISE			| E-mail:
52 Fletcher St			|  (priv) malaise@alphalink.com.au
HAWTHORN EAST    VIC    3123	|  (prof) malaise@thomson.starway.net.au
AUSTRALIA




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-12-16  0:00 ` Pascal MALAISE
@ 1997-12-16  0:00   ` Larry Kilgallen
  1997-12-17  0:00     ` Pascal MALAISE
  0 siblings, 1 reply; 13+ messages in thread
From: Larry Kilgallen @ 1997-12-16  0:00 UTC (permalink / raw)



In article <349646A2.1A013246@alphalink.com.au>, Pascal MALAISE <malaise@alphalink.com.au> writes:

> In C or ADA, you are likely to get a bus error or an unaligned access,
> more or less recovered by the operating system or your application :-(
> 
> This is because processors make assumptions about the addresses of given
> data types:
> character/byte - any address
> 16 bits "word" - address is a multiple of 2
> 32 bits "int"  - address is is a multiple of 4
> 64 bits "long" - address is a multiple of 8
> 
> When you declare your array of bytes/characaters, the compiler
> implements
> the array starting at any address. When you cast, the compiler will
> consider the new (integer) data as aligned and the processor will trap.

Whether the compiler (for any language) assumes that such variables
are aligned depends on the quality of the compiler and what you have
told it.

The DEC compilers for various languages on Alpha have many hooks for
indicating what assumptions should be made regarding alignment.  The
result is to tune the generated code between that which presumes worst
case alignment and that which presumes best case alignment.

Larry Kilgallen




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-12-16  0:00   ` Larry Kilgallen
@ 1997-12-17  0:00     ` Pascal MALAISE
  1997-12-18  0:00       ` David J. Fiander
  0 siblings, 1 reply; 13+ messages in thread
From: Pascal MALAISE @ 1997-12-17  0:00 UTC (permalink / raw)
  To: Kilgallen


Larry Kilgallen wrote:
> 
> In article <349646A2.1A013246@alphalink.com.au>, Pascal MALAISE <malaise@alphalink.com.au> writes:
> > When you declare your array of bytes/characaters, the compiler
> > implements
> > the array starting at any address. When you cast, the compiler will
> > consider the new (integer) data as aligned and the processor will trap.
> 
> Whether the compiler (for any language) assumes that such variables
> are aligned depends on the quality of the compiler and what you have
> told it.
> 
> The DEC compilers for various languages on Alpha have many hooks for
> indicating what assumptions should be made regarding alignment.  The
> result is to tune the generated code between that which presumes worst
> case alignment and that which presumes best case alignment.

Let's take an example:
char buf[500];
int i;

i = * (int*) buf;  /* or &buf[x] */

The compiler will allocate i at a correct address (multiple of 4).
But buff is often allocated at any address (probably to save stack
space).
The C cast will often be compiled in assembly by a load_int/store_int,
the store generating the analigned access.

As far as I know, this problem would not happen in full ADA because the
instanciation of unchecked_conversion will be compiled as a call to
something
like memcpy, a procedure which does not make any assumption about
alignment of arguments.
We loose performance but gain reliability.

Back to the debate, and thinking about it:
What is the use of alignment clauses?
The only one I can see is, by instance, when you declare an array
of bytes/characters and intend to pass it by address to a procedure
in another language which will assume that this address points to
a more elaborated data structure (int, record...):
type T1 is array (1..500) of CHARACTER;
type T2 is record 
  THE_ARRAY : T1;
end record;
for T2 use 
  record at mod 4;
end record;

procedure C_CALL (A : in SYSTEM.ADRESS)
pragma IMPORT (C, C_CALL, "c_call"); -- or pragma INTERFACE

in C:
void c_call (int *p);

Without the alignment clause on T2, c_call may trap when using *p


BTW, I don't know what we should expect from a "modern" ADA compiler
about such representation clause:
type T is record
  F1 : INTEGER;
  F2 : CHARACTER;
  F3 : INTEGER;
end record;
for T use
  F1 at 0 range 0 .. 31;
  F2 at 4 range 0 .. 7;
  F3 at 5 range 0 .. 31;
end record;

Should it refuse it, or generate byte accesses for F3?
(Without the clause, of course, some gap would be generated between F2
and F3.)

Practically speaking
1. it is more likely to have the "high" level data structure implemented
in ADA, calling C and giving it by address and C taking in as a char*.
So no need for alignment/representation clause.
2. we have C and ADA processes exchanging TCP messages, and in the
message record types, we put longs first, then ints, then shorts, then
bytes.
We declare similar types in ADA and C and let each compiler manage to
implement
the stuff.
Believe it or not, it works without clause in 99.99% of the cases.
Compilers, even stupid (what I don't believe) have a similar logic.
This approach appears to be the most practical and portable.

My recomendation, based on ADA 83/C interfaces (DG, ULTRIX, DEC UNIX)
would be:
"Use representation clauses as a last option only", which mainly applies
to all the stuff in chapter 13.

-- 
Pascal MALAISE			| E-mail:
52 Fletcher St			|  (priv) malaise@alphalink.com.au
HAWTHORN EAST    VIC    3123	|  (prof) malaise@thomson.starway.net.au
AUSTRALIA




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-12-18  0:00       ` David J. Fiander
@ 1997-12-18  0:00         ` Robert Dewar
  1997-12-18  0:00         ` Tucker Taft
  1 sibling, 0 replies; 13+ messages in thread
From: Robert Dewar @ 1997-12-18  0:00 UTC (permalink / raw)



David said

<<I've seen other comments that indicate that the runtime cost of a
call to Unchecked_Conversion is going to be a function call of
some sort, and I have just one question: "Why?"
>>

No, you have not seen any such comments (at least I haven't). Probably the
point is that you misinterpreted comments about the semantics. Semantically,
UC *is* a function call, to which a *value* is passed, and a value is
returned (although there is permission to pass and return by reference in
Ada 95). 

However, saying t 
hat the semantics is that of a function call does not mean that there
will the "runtime cost of a call ...", that is a misunderstanding,
no of course not!





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-12-17  0:00     ` Pascal MALAISE
@ 1997-12-18  0:00       ` David J. Fiander
  1997-12-18  0:00         ` Robert Dewar
  1997-12-18  0:00         ` Tucker Taft
  0 siblings, 2 replies; 13+ messages in thread
From: David J. Fiander @ 1997-12-18  0:00 UTC (permalink / raw)



Pascal MALAISE <malaise@alphalink.com.au> writes:
> As far as I know, this problem would not happen in full ADA because the
> instanciation of unchecked_conversion will be compiled as a call to
> something
> like memcpy, a procedure which does not make any assumption about
> alignment of arguments.
> We loose performance but gain reliability.

I've seen other comments that indicate that the runtime cost of a
call to Unchecked_Conversion is going to be a function call of
some sort, and I have just one question: "Why?"

It would seem to me that if I have an object of some sort, and I
call Unchecked_Conversion on it, if the type is small enough
(in C terms converting a pointer to an int), why shouldn't the
compiler just generate a "load ptr/store int" instruction
sequence?  Now, for larger objects, the compiler will have to
perform a block move to effect the conversion, either via a
runtime library call or by open-coding the block move, but that
depends entirely on the H/W support for block moves.

- David




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Representation clauses and records
  1997-12-18  0:00       ` David J. Fiander
  1997-12-18  0:00         ` Robert Dewar
@ 1997-12-18  0:00         ` Tucker Taft
  1 sibling, 0 replies; 13+ messages in thread
From: Tucker Taft @ 1997-12-18  0:00 UTC (permalink / raw)



David J. Fiander (davidf@mks.com) wrote:

: Pascal MALAISE <malaise@alphalink.com.au> writes:
: > As far as I know, this problem would not happen in full ADA because the
: > instanciation of unchecked_conversion will be compiled as a call to
: > something
: > like memcpy, a procedure which does not make any assumption about
: > alignment of arguments.
: > We loose performance but gain reliability.

: I've seen other comments that indicate that the runtime cost of a
: call to Unchecked_Conversion is going to be a function call of
: some sort, and I have just one question: "Why?"

I have never seen an implementation that imposes function call
overhead for unchecked-conversion.  This sounds like an
"urban myth" ;-).  Unchecked conversion does involve making a copy,
but not a function call.

: It would seem to me that if I have an object of some sort, and I
: call Unchecked_Conversion on it, if the type is small enough
: (in C terms converting a pointer to an int), why shouldn't the
: compiler just generate a "load ptr/store int" instruction
: sequence?  Now, for larger objects, the compiler will have to
: perform a block move to effect the conversion, either via a
: runtime library call or by open-coding the block move, but that
: depends entirely on the H/W support for block moves.

Right.  Whether block moves/copies involve out-of-line code is 
independent of the use of unchecked-conversion.

: - David

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~1997-12-18  0:00 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <347000b1.4909762@news.geccs.gecm.com>
1997-11-21  0:00 ` Representation clauses and records Brian Nettleton
1997-11-21  0:00   ` Matthew Heaney
1997-11-21  0:00   ` Brian Nettleton
1997-11-24  0:00     ` Martin M Dowie
1997-11-25  0:00       ` Robert Dewar
1997-11-27  0:00         ` Martin M Dowie
     [not found]   ` <347a8dc3.3438484@news.geccs.gecm.com>
1997-11-25  0:00     ` Matthew Heaney
1997-12-16  0:00 ` Pascal MALAISE
1997-12-16  0:00   ` Larry Kilgallen
1997-12-17  0:00     ` Pascal MALAISE
1997-12-18  0:00       ` David J. Fiander
1997-12-18  0:00         ` Robert Dewar
1997-12-18  0:00         ` Tucker Taft

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox