分配上的Fortran可分配数组的内存位置? [英] Memory location of Fortran allocatable arrays on assigment?

查看:224
本文介绍了分配上的Fortran可分配数组的内存位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这样的东西:

real, dimension(:), allocatable :: S
integer, dimension(:) :: idx
...
S = S(idx)

其中 S idx 在分配之前已正确分配/初始化。

where S and idx are properly allocated/initialized before the assignment.

Fortran标准对 S 的内存位置(地址)说什么?入伙后应该留在同一地方吗?是否未指定(由编译器决定)?如果 S 不是可分配的,会有所不同吗?

What does the Fortran standard(s) say, if anything, about the memory location (address) of S? Should it stay in the same place after the assigment? Is it unspecified (up to the compiler to decide)? Does it make a difference if S is not allocatable?

完整示例:

$ cat test.f90 
program test
implicit none
real, dimension(:), allocatable :: S
integer :: i, idx(7) = [1,3,5,7,2,4,6]

allocate(S(size(idx)))
do i=1,size(S)
  S(i) = i*i
end do

write(6,*) S
write(6,*) loc(S)

S = S(idx)

write(6,*) S
write(6,*) loc(S)

S(:) = S(idx)

write(6,*) S
write(6,*) loc(S)

deallocate(S)

end program

$ sunf90 -V
f90: Studio 12.6 Fortran 95 8.8 Linux_i386 2017/05/30

$ sunf90 test.f90 ; ./a.out 
 1.0 4.0 9.0 16.0 25.0 36.0 49.0
 37518752
 1.0 9.0 25.0 49.0 4.0 16.0 36.0
 37519840
 1.0 25.0 4.0 36.0 9.0 49.0 16.0
 37519840

(假设 loc 给出了一些信息

推荐答案

在您的示例中, idx 具有与 S 相同的范围(元素数)。如果是这样,则 S(idx)的形状与 S 的形状相同,标准说没有重新分配 S 。但是,如果它们不同,则标准说 S 被释放,然后重新分配为 S(idx) 。如果发生这种重新分配/重新分配,则基址保持不变是不可预测的(可能不太可能)。

In your example, it matters whether idx has the same extent (number of elements) as S. If it does, then the shape of S(idx) is the same as that of S and the standard says that no reallocation of S occurs. But if they are different, then the standard says S is deallocated, then reallocated to the shape of S(idx). If this deallocation/reallocation occurs, it is unpredictable (and probably unlikely) if the base address remains the same.

然后,您询问 S是否不可分配-在这种情况下,形状必须匹配,并且只是数据的副本,尽管可能存在重叠,但可能通过临时数组。

You then asked what if S was not allocatable - in this case, the shapes must match and it's just a copy of data, though possibly via a temporary array since there is overlap.

-编辑2019年8月24日-

-- Edit August 24, 2019 --

我在此调查了J3(美国Fortran标准委员会)电子邮件列表。共识是,在没有 TARGET 的情况下,更改地址符合标准,尽管不止一个成员质疑这是否是一个好主意。显然,编译器开发人员认为,分配新的存储并执行一个副本比保留相同的存储并进行两个副本(将一个副本保存到一个临时副本,然后再复制回到 S )要快。 )如果要复制很多数据,我可能会认为这是有益的-也许-但在较小的情况下不会。

I polled the J3 (US Fortran standards committee) email list on this. The consensus was that, in the absence of TARGET, the "changing address" was standard-conforming, though more than one member questioned whether it was a good idea. The compiler developers evidently feel that allocating new storage and doing a single copy is faster than keeping the same storage and doing two copies (one to a temp and then one back to S.) I might see this as beneficial if a lot of data was being copied - maybe - but not in smaller cases.

无论如何,您都可以禁用通过为 S 提供 TARGET 属性来实现此行为。

In any event you can, as you discovered, disable this behavior by giving S the TARGET attribute.

这篇关于分配上的Fortran可分配数组的内存位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆