bio
bio

Reputation: 511

fortran90: addressing memory location

I have a fortran90 code to optimize. Now I'd like to access memory location of a structure in an external loop, and then access the deepest structure in a nested loop. Something like this:

sample fortran loop - legacy version

do i = 1, N
  ii = some integer
  jj = some other integer
  do j = 1, M
    c = a(ii, jj)%b(i)
  enddo
enddo

has to become:

second fortran loop - what I would like to write

do i = 1, N
  ii = some integer
  jj = some other integer
  pointertoa = &a(ii, jj) !I know it's not correct in fortran, that is the question!
  do j = 1, M
    c = pointertoa%b(i)
  enddo
enddo

I have this (sample) C code working as I expect:

Working memory addressing in C

#include <stdio.h>

struct mem{
  int a;
    struct mm{
    int b;
    float v;
  } mmm;
};

void main(){

  struct mem *m, dum;

  dum.a = 12;
  dum.mmm.b = 5;
  dum.mmm.v = 3.2;

  m = &dum; //m is given dum memory address

  printf("dum.a = %d\n", dum.a);
  printf("dum.mmm.b = %d\n", dum.mmm.b);
  printf("dum.mmm.v = %f\n", dum.mmm.v);

  printf("m.a = %d\n", m->a);
  printf("m.mmm.b = %d\n", m->mmm.b);
  printf("m.mmm.v = %f\n", m->mmm.v);

}

A couple of question:

  1. How would you do the same I did in C in fortran90?
  2. Do you think the second fortran loop would speed up the code?

Upvotes: 0

Views: 1115

Answers (1)

High Performance Mark
High Performance Mark

Reputation: 78354

Fortran will make it very very difficult for you to get the memory address of a variable or anything else for that matter. The tricks and techniques you may have learned in C, messing around with pointers and memory addresses, just aren't supported in Fortran. Nor, generally, are they needed within Fortran's core application domains. Your question rather suggests you are trying to write C in Fortran. Don't.

Now I've got that off my chest, you may be able to achieve what you want using the recently-introduced associate construct. Something like

  associate(pointertoa => a(ii, jj)) 
  do j = 1, M
    c = pointertoa%b(i)
  enddo
  end associate

Whether this achieves your efficiency goals I haven't a scooby. But I'll be surprised if it does. Optimising access to array elements is something that Fortran compilers have been working on for 50+ years and they're really quite good at it.

EDIT, in response to OP's first comment ...

If your compiler supports associate you can certainly use it. But if someone is going to look over your shoulder and hit you painfully on the head if you use any feature introduced to Fortran after publication of the 90 standard then it's up to you whether or not you take the hit. The compiler ain't going to care, nor is the compiled code. associate is part of the standard and Fortran has a very good record of maintaining backwards compatibility so the likelihood that a future compiler will get upset is very small.

In writing your C function don't forget to take advantage of loop unrolling, memory prefetching, multiple instruction pipelines, vector operations, common subexpression elimination, all that sort of shit. If you manage to write a C function that outperforms the product of a Fortran compiler with optimisation turned up to 11 come back with the data to prove it and I'll eat my hat.

And, while I'm writing again, I note that the loop

  do j = 1, M
    c = pointertoa%b(i)
  enddo

is almost entirely redundant and a good optimising compiler would just create code to execute c = pointertoa%b(i) once.

Upvotes: 3

Related Questions