Code Comments
Programming Forum and web based access to our favorite programming groups.How can you convert the idea of a fortran common to C++? ie /common/eparams3d/epsilon, akL, akD, as, af Jason
Post Follow-up to this messageJason 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 ?
Post Follow-up to this messageJason 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
Post Follow-up to this messageglen 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
Post Follow-up to this messageTom 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
Post Follow-up to this messageTom 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
Post Follow-up to this messageRichard E Maine wrote: > Tom McGlynn <tam@lheapop.gsfc.nasa.gov> writes: I wrote: > 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
Post Follow-up to this messageglen 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
Post Follow-up to this messageTom 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
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.