- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
I need to interpret a 2-element integer(4) array as an integer(8) scaler. Currently I'm using
! One of the next two is a dummy argument integer(4) :: pos(2) integer(8) :: cpos cpos = transfer(pos,cpos) ! or pos = transfer(cpos,pos)
These two expressions work as expected but I know from experience that transfer can be slow so I was wondering if there is a nifty trick with pointers I could use instead.
Thanks.
Link kopiert
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
You could do it numerically instead:
cpos = pos(1) * 2_8**32 + pos(2)
and:
pos(1) = mod( cpos, 2_8**32 )
pos(2) = cpos / 2_8**32
not as elegant perhaps, but it should not suffer from slowness. If you use the right bit manipulation functions, it could be even faster, I guess.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
For data this small, TRANSFER will be faster than anything else. If you had a lot of data to reinterpret, you can do a "cast" like this:
use, intrinsic :: ISO_C_BINDING integer(8), pointer, dimension(:) :: i8p ... call C_F_POINTER(C_LOC(pos),i8p,[100]) ! i8p now points to the storage of pos as an array of 100 elements
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Well I'm all for keeping things simple so I'll leave this case as transfer. Thanks for the other ideas.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
I forgot - you should put the TARGET attribute on anything you'll be referencing through a pointer.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
You can also use UNION, MAP.
If you do this often, place the map in a user defined type then reference the appropriate mapping via %
Jim Dempsey
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
No, please don't use extensions UNION/MAP unless there is no alternative. Besides, these have to go in a derived type (STRUCTURE/RECORD) which requires significant coding changes based on Simon's request.
Heck, if you're going there, use EQUIVALENCE, but that's not allowed on dummy arguments and is not recommended either.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Simon Geard wrote:
.. I know from experience that transfer can be slow ..
@Simon Geard,
Will it be possible for you to elaborate further on your "transfer can be slow" comment? It is "slow" relative to what? Do you have any performance measures you can share, however qualitative or sketchy, in terms of what you meant by above. For example, for the size of datasets of interest to you, have you compared a similar operation with C union or anything else (perhaps EQUIVALENCE) relative to Fortran TRANSFER and taken stock of some penalty with the TRANSFER option? If so, what is your observation?
Thanks much,
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Steve,
I am aware that the perfectly good UNION is frown upon with code "modernization". IMHO "modernization" is failing if it does not include a means to convienently cast types.
I haven't tried this, but would you happen to know if your "cast" in post #3, when placed in a function, completely inlines to the point were no code is generated? (e.g. no temporary pointer or temporaries)
Jim Dempsey
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Yes, it generates code. But not much, and I would not worry about it unless a performance analysis shows it's a bottleneck.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Here is an example where the use of TRANSFER has no overhead. Compiled with gfortran -O3 -c, the following two versions of a pass-through subroutine yield the same object code (except for the '4'/'8' difference in the subroutine names).
Version A:
subroutine sub4(i4) integer(4) :: i4(2) integer(8) :: i8 ! call sub(transfer(i4,i8)) return end subroutine
Version B:
subroutine sub8(i8) integer(8) :: i8,k8 ! k8=i8 call sub(k8) return end subroutine
- RSS-Feed abonnieren
- Thema als neu kennzeichnen
- Thema als gelesen kennzeichnen
- Diesen Thema für aktuellen Benutzer floaten
- Lesezeichen
- Abonnieren
- Drucker-Anzeigeseite