Home > Archive > Fortran > October 2004 > Common --- question
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Common --- question
|
|
|
| How can you convert the idea of a fortran common to C++?
ie /common/eparams3d/epsilon, akL, akD, as, af
Jason
| |
| Madhusudan Singh 2004-10-20, 3:56 am |
| Jason wrote:
> How can you convert the idea of a fortran common to C++?
>
> ie /common/eparams3d/epsilon, akL, akD, as, af
>
> Jason
Probably using public classes, but then don't you think this question is
best posed in a C/C++ NG ?
| |
| glen herrmannsfeldt 2004-10-20, 3:56 am |
| Jason wrote:
> How can you convert the idea of a fortran common to C++?
> ie /common/eparams3d/epsilon, akL, akD, as, af
COMMON isn't padded, but C and C++ struct variables are.
Write it as an external struct containing the appropriate
variables. Possibly with _ added onto the name.
-- glen
| |
| Tom McGlynn 2004-10-20, 4:06 pm |
| glen herrmannsfeldt wrote:
> Jason wrote:
>
>
>
>
>
> COMMON isn't padded,...
Is that true? I thought that as long as the compiler was consistent
it could add padding? E.g., it could align everything on 8 byte
boundaries. Been a while since I've used common much though.
Regards,
Tom McGlynn
| |
| Dick Hendrickson 2004-10-20, 4:06 pm |
|
Tom McGlynn wrote:
> glen herrmannsfeldt wrote:
>
>
>
>
> Is that true? I thought that as long as the compiler was consistent
> it could add padding? E.g., it could align everything on 8 byte
> boundaries. Been a while since I've used common much though.
>
It can align and pad things if it wants. The problem comes
with different layouts of common blocks in different
routines.
Fortran allows common blocks to be different and basically
treats them as there were a bunch of ordered EQUIVALENCE
statements among the different commons. That makes it
difficult for a compiler to insert internal padding in
the common list, especially if it allows separate
compilation.
Common blocks are likely to be loaded to start on an
8 byte boundry, but after that things are normally
plopped in without internal padding. The rule of thumb
is to put double precision variables first in the
common list, followed by single word entities.
Dick Hendrickson
> Regards,
> Tom McGlynn
| |
| Richard E Maine 2004-10-20, 4:06 pm |
| Tom McGlynn <tam@lheapop.gsfc.nasa.gov> writes:
> glen herrmannsfeldt wrote:
>
>
> Is that true? I thought that as long as the compiler was consistent
> it could add padding? E.g., it could align everything on 8 byte
> boundaries. Been a while since I've used common much though.
The "as long as the compiler was consistent" part is a really huge
caveat. In many ways, COMMON is incredibly complicated. Those people
who think COMMON is simple to understand usually don't understand it. :-)
(The complications go far deeper than anything covered below).
Yes, it can be simple if you, as a user, stick to the simple cases,
as many users do. But compilers have to handle at least all the legal
cases (and some compilers handle quite a bit more).
Aligning "everything" on 8-byte boundaries isn't going to work
(except on machines where single precision is 8 bytes - could work
there, but I doubt that's what you had in mind).
For example, you could have
common /com/ a,b,i ; real a,b; integer i
and
common /com/ d,i; double precision d; integer i
in two different subroutines. This is prefectly standard and the
"i" variables have to line up in the same place. (speaking sloppily,
but you don't want the standard-speak for this). That won't happen
if a and b are both 8-byte aligned (unless d takes up 16 bytes).
Note that some compilers have switches to control whether you want
them to do common according to the standard or with decent performance.
That's because the standard can esentially force doubles to be aligned
on 4-byte boundaries (on machines where single is 4 bytes), which can
be a performance killer.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| glen herrmannsfeldt 2004-10-20, 4:06 pm |
|
Richard E Maine wrote:
> Tom McGlynn <tam@lheapop.gsfc.nasa.gov> writes:
I wrote:
[color=darkred]
[color=darkred]
> The "as long as the compiler was consistent" part is a really huge
> caveat. In many ways, COMMON is incredibly complicated.
(snip)
> For example, you could have
> common /com/ a,b,i ; real a,b; integer i
> and
> common /com/ d,i; double precision d; integer i
> in two different subroutines. This is prefectly standard and the
> "i" variables have to line up in the same place. (speaking sloppily,
> but you don't want the standard-speak for this). That won't happen
> if a and b are both 8-byte aligned (unless d takes up 16 bytes).
And even more, consider
doubleprecision d, e
integer i, j, k
common /com2/ i, d, j, e, k
and
real w, x, y, z
integer i, j, k
common /com2/ i, w, x, j, y, z, k
If d and/or e are padded they won't align with w,x and y,z,
and k won't align with k.
I always put double precision variables first in whatever
language I use.
I remember the OS/360 Fortran library had a routine that would
trap (SPIE, actually) the exception for alignment errors, copy
the data, do the operation on the copied data, and copy the
results back. On most machines that was very slow, on the
360/91 it didn't work at all. The 91 was pipelined and by the
time the interrupt was processed many more instructions had been
processed, the instruction address didn't point to the right place,
and the results could have been changed, anyway.
Many RISC machines won't do unaligned memory operations at all,
and those machines that do usually do it slower.
-- glen
| |
| Tom McGlynn 2004-10-20, 4:06 pm |
| glen herrmannsfeldt wrote:
>
>
> Richard E Maine wrote:
>
>
>
> I wrote:
>
>
>
>
>
>
>
.... many examples by Richard and Greg about how it's difficult to
pad common elided.
If I can expose my ignorance a little further: How does this
work when types are defined using kind variables?
As I understand the space rules:
Double precision is required to take twice as much space
as the default real.
Default reals, integers and logicals need to take the same amount of space
Complex numbers take twice as much space as the corresponding reals
But I don't know of any rules that apply to variables defined with
an explicit kind.
But how does one know how much space a REAL(kind=m) takes versus
a REAL(kind=n)? Or INTEGER or LOGICAL? I gather that there are
compilers with a 10-byte real. If I have such a real how
does the standard permit overlaying it with other types using
equivalence or common? Or is this like mixing in character variables
and forbidden in some way?
Regards,
Tom McGlynn
| |
| Richard E Maine 2004-10-20, 4:06 pm |
| Tom McGlynn <tam@lheapop.gsfc.nasa.gov> writes:
> If I can expose my ignorance a little further: How does this
> work when types are defined using kind variables?
Except for the kinds that correspond to single and double,
the amount of space taken by each kind is processor-dependent.
In terms of what this means for common, each kind other than
single or double is required to correspond only to something
of the same kind in other instances of the common.
Thus, a compiler could validly pad things like 10-byte reals
in common so that there was, say, 2 bytes of padding after
them. That would keep there from being too awfully much "damage"
from misalignment and wouldn't violate anything in the standard
that I see. Whether it would violate some user expectations, I
don't know, but my guess is that there are contradictory expectations
in different users, so you'll never be able to do what they all
expect.
My advice to users is to avoid abusing poor compilers by explicitly
depending on whether there is or is not padding in such a case.
Explicitly depending on it puts you outside the bounds of the
standard.
And, as others have mentioned, generally put larger things earlier
in common, if you have to use common at all. But I'm not sure
whether that is adequate when 10-byte reals are in the picture.
Hard to give advice on how to make sure that 10-byte reals are
stored with efficient alignment (whatever efficient for them is,
which I don't know for sure). Preferably, I'd avoid putting such
things in common at all (use modules).
> But how does one know how much space a REAL(kind=m) takes versus
> a REAL(kind=n)? Or INTEGER or LOGICAL?
Default integer and logical are required to take the same space as
default real (aka single).
If you specifically want to know how much space nondefault kinds take,
there are multiple tricks... which I don't think I'll cover here
because I've gone for long enough. If you really want more detail on
that, ask again separately and I'll make a go at it. But for current
purposes, no, they can't be "mucked with" by common.equivalence tricks
(anyway, not legally - many compilers allow it as a natural extension).
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
|
|
|
|
|