fortran90:寻址内存位置

时间:2014-10-13 11:19:15

标签: c pointers fortran90 memory-address

我有一个fortran90代码来优化。 现在我想访问外部循环中结构的内存位置,然后访问嵌套循环中最深的结构。 像这样:

示例fortran循环 - 旧版本

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

必须成为:

第二个fortran循环 - 我想写什么

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

我有这个(示例)C代码正常工作:

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);

}

有几个问题:

  1. 你怎么会像我在Fortran90中做的那样做?
  2. 你认为第二个fortran循环会加速代码吗?

1 个答案:

答案 0 :(得分:2)

Fortran会让您很难获得变量或其他任何内容的内存地址。你可能在C中学到的技巧和技巧,乱用指针和内存地址,但Fortran不支持。通常,Fortran的核心应用领域也不需要它们。你的问题反而暗示你正在尝试在Fortran中编写C语言。不。

现在我已经把它放在胸前了,你可以使用最近推出的associate结构实现你想要的效果。像

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

这是否达到了你的效率目标,我没有一个好看的东西。但如果确实如此,我会感到惊讶。优化对数组元素的访问是Fortran编译器已经工作了50多年的事情,他们真的非常擅长。

编辑,回应OP的第一条评论......

如果您的编译器支持associate,您当然可以使用它。但是,如果你在发布90标准之后使用Fortran引入的任何功能,那么如果有人想看看你的肩膀并痛苦地击中你,那么你是否接受了击中。编译器不关心,编译代码也不关心。 associate是标准的一部分,Fortran在保持向后兼容性方面有很好的记录,因此未来的编译器可能会受到很大的干扰。

在编写C函数时,不要忘记利用循环展开,内存预取,多指令流水线,向量运算,常见的子表达式消除等等。如果你设法编写一个优于Fortran编译器产品的C函数,优化结果最多为11,请回来用数据来证明它,我会吃掉我的帽子。

而且,当我再次写作时,我注意到了循环

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

几乎完全是冗余的,一个好的优化编译器只会创建一次执行c = pointertoa%b(i)的代码。