我有一个fortran90代码来优化。 现在我想访问外部循环中结构的内存位置,然后访问嵌套循环中最深的结构。 像这样:
do i = 1, N
ii = some integer
jj = some other integer
do j = 1, M
c = a(ii, jj)%b(i)
enddo
enddo
必须成为:
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代码正常工作:
#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);
}
有几个问题:
答案 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)
的代码。