本地可分配数组和自动数组的区别 [英] Difference between local allocatable and automatic arrays

查看:24
本文介绍了本地可分配数组和自动数组的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对以下摘录中 alloc_arrayautomatic_array 之间的区别很感兴趣:

I am interested in the difference between alloc_array and automatic_array in the following extract:

subroutine mysub(n)
integer, intent(in)  :: n
integer              :: automatic_array(n)
integer, allocatable :: alloc_array(:)

allocate(alloc_array(n))
...[code]...

我非常熟悉分配的基础(对高级技术不太了解)知道分配允许您在代码中间更改数组的大小(如所指出的在这个问题中),但我有兴趣考虑这个案例你不需要需要改变数组的大小;它们可能会被传递到其他子程序进行操作,但是代码中的变量和任何子程序的唯一目的是保存维度为 n 的数组的数据(并且可能更改数据,但不尺寸).

I am familiar enough with the basics of allocation (not so much on advanced techniques) to know that allocation allows you to change the size of the array in the middle of the code (as pointed out in this question), but I'm interested in considering the case where you don't need to change the size of the array; they might be passed onto other subroutines for operation, but the only purpose of both variables in the code and any subroutine is to hold the data of an array of dimension n (and maybe change the data, but not the size).

(1) 内存使用量有什么不同吗?我不是底层程序的专家,但我对它们的重要性以及它们如何影响更高层程序的知识知之甚少.级别编程(我正在谈论的那种经验:曾经尝试在 Fortran 中运行大代码时遇到了一个我不明白的错误,系统管理员告诉我哦,是的,您可能正在使堆栈饱和;尝试添加这个运行脚本中的行";任何能让我深入了解在实际编码时如何考虑这些事情而不必在以后修补它们的东西都是受欢迎的).人们告诉我,它可能依赖于许多其他东西,例如编译器或架构,但我从这些回应中解释说,他们并不完全确定这是怎么回事.它是否绝对依赖于多种因素,还是编码中是否存在默认/预期行为,然后可能会被可选的编译关键字或系统首选项覆盖?

(1) Is there any difference in memory usage? I am not an expert in low level procedures, but I have a very slight knowledge of how they matter and how they can impact on the higher level programming (kind of experience I'm talkng about: once trying to run a big code in fortran I was getting a mistake I didn't understand, sysadmin told me "oh, yeah, you are probably saturating the stack; try adding this line in your running script"; anything that gives me insight into how to consider this things when actually coding and not having to patch them later is welcomed). I've been told by people that it might be dependent on many other things like compiler or architecture, but I interpreted from those responses that they were not completely sure of exactly how this was so. Is it so absolutely dependant on a multitude of factors or is there a default/intended behavior in the coding that may then be over-riden by optional compiling keywords or system preferences?

(2) 子程序是否有不同的接口需求? 再说一遍,不是专家,但之前也遇到过,因为我声明子程序变量的方式,最后不得不将子程序放在一个模块中.我已经了解到这可能会因我是否使用可分配变量的特殊内容而有所不同.我正在考虑这样一种情况:我对变量所做的一切都可以由 allocatables 和自动完成,而不是故意使用任何特定的 allocatables(除了使用前的分配).

(2) Would the subroutines have different interface needs? Again, not an expert, but it had happened to me before that because of the way I declare variables of subroutine, I end up having to put the subroutines in a module. I've been given to understand this may vary depending on whether I use things that are special for allocatable variables. I am thinking about the case in which everything I do with the variables can be done both by allocatables and automatics, not intentionally using anything specific of allocatables (other than allocation before usage, that is).

最后,万一这是有用的:我问的原因是因为我们是在一个小组中开发,我们最近注意到不同的人以不同的方式使用这两个声明,我们需要确定这是否可以留给个人偏好,或者是否可能有任何理由表明设置明确的标准(以及如何设置该标准)可能是一个好主意.我不需要非常详细的答案,我正在尝试确定这是否是我应该做的研究,以谨慎使用它以及应该在哪些方面进行研究.

Finally, in case this is of use: the reason I am asking is because we are developing in a group and we have recently noticed different people use those two declarations in different ways and we needed to determine if this is something that can be left to personal preference or if there might be any reasons why it might be a good idea to set a clear criteria (and how to set that criteria). I don't need extremely detailed answers, I am trying to determine if this is something I should be doing research about to be careful on how we use it and in what aspects of it should the research be directed.

虽然我很想知道分配可以完成的有趣的技巧",但与大小可变性的需要没有直接关系,但我将这些技巧留给未来可能的后续问题,并重点关注严格的功能差异(意思是:我明确告诉编译器如何处理我的代码).我提到的两个项目是我根据以前的经验可以想出的东西,但是我遗漏了任何其他重要的项目并且应该考虑,请务必提及它们.

Though I would be interested to know of "interesting tricks" than can be done with allocation but are not directly related to the need of having size variability, I am leaving those for a possible future follow-up question and focusing here on the strictly functional differences (meaning: what I am explicitly telling compilers to do with my code). The two items I mentioned are the thing I could come up with due to previous experiences, but any other important one that I am missing and should consider, please do mention them.

推荐答案

为了清楚起见,我将简要提及术语.这两个数组都是局部变量和秩为1的数组.

For the sake of clarity, I'll briefly mention terminology. The two arrays are both local variables and arrays of rank 1.

  • alloc_array 是一个可分配的数组;
  • automatic_array 是一个显式形状的自动对象.
  • alloc_array is an allocatable array;
  • automatic_array is an explicit-shape automatic object.

作为局部变量,它们的范围是过程的范围.自动数组和未保存的可分配数组在过程执行完成时结束(可分配数组被释放);自动对象无法保存,保存的可分配对象不会在执行完成时释放.

Being local variables their scope is that of the procedure. Automatic arrays and unsaved allocatable arrays come to an end when execution of the procedure completes (with the allocatable array being deallocated); automatic objects cannot be saved and saved allocatable objects are not deallocated on completion of execution.

同样,在链接问题中,在分配语句之后,两个数组的大小都是 n.这仍然是两个非常不同的事情.当然,可分配数组可以改变其分配状态并移动其分配.我将把这两个(大部分)都排除在这个答案的范围之外.当然,一个可分配的数组一旦被分配就不必更改这些内容.

Again, as in the linked question, after the allocation statement both arrays are of size n. These are still two very different things. Of course, the allocatable array can have its allocation status changed and its allocation moved. I'll leave both of those (mostly) out of the scope of this answer. An allocatable array, of course, doesn't have to have these things changed once it's been allocated.

内存使用

关于该问题的先前修订版的部分争议在于内存使用的概念定义不明确.Fortran,作为一种语言定义,告诉我们两个数组大小相同,存储布局相同,并且都是连续的.除此之外,您还会听到很多术语:特定于实现依赖处理器.

What was partly contentious about a previous revision of the question is how ill-defined the concept of memory usage is. Fortran, as a language definition, tells us that both arrays come to be the same size and they'll have the same storage layout, and are both contiguous. Beyond that, much follows terms you'll hear a lot: implementation specific and processor dependent.

您在评论中表达了对 ifort 的兴趣.所以我不会走得太远,我会坚持使用那个编译器.其他编译器也有类似的概念,只是名称和选项不同.

In a comment you expressed interest in ifort. So that I don't wander too far, I'll stick to that one compiler. Other compilers have similar concepts, albeit with different names and options.

通常,ifort 会将自动对象和临时数组放入堆栈.有一个(默认)编译器选项 -no-heap-arrays 描述为有效

Often, ifort will place automatic objects and array temporaries onto stack. There is a (default) compiler option -no-heap-arrays described as having effect

编译器将自动数组和临时数组放入堆栈存储区.

The compiler puts automatic arrays and temporary arrays in the stack storage area.

使用替代选项 -heap-arrays 可以稍微控制一下:

Using the alternative option -heap-arrays allows one to control that slightly:

此选项将自动数组和为临时计算创建的数组放在堆上而不是堆栈上.

This option puts automatic arrays and arrays created for temporary computations on the heap instead of the stack.

可以控制选择堆/堆栈的大小阈值(如果在编译时已知):

There is a possibility to control size thresholds for which heap/stack would be chosen (when that is known at compile-time):

如果编译器在编译时无法确定大小,它总是将自动数组放在堆上.

If the compiler cannot determine the size at compile time, it always puts the automatic array on the heap.

由于 n 不是常数,因此无论指定的大小如何,都希望 automatic_array 使用此选项位于堆上.要在编译时确定数组的大小 n,编译器可能需要进行大量的代码分析,即使可能.

As n isn't a constant, one would expect automatic_array to be on the heap with this option, regardless of the size specified. To determine the size, n, of the array at compile time, the compiler would potentially need to do quite a bit of code analysis, even if it is possible.

可能还有更多要说的,但如果我尝试,这个答案会太长.然而,需要注意的一件事是,自动本地对象和(Fortran 90 之后)可分配的本地对象预计不会泄漏内存.

There's probably more to be said, but this answer would be far too long if I tried. One thing to note, however, is that automatic local objects and (post-Fortran 90) allocatable local objects can be expected not to leak memory.

接口需求

子程序mysub的接口要求没有什么特别之处:局部变量对此没有影响.任何对隐式接口感到满意的程序单元调用.你问的是如何使用这两个本地数组.

There is nothing special about the interface requirements of the subroutine mysub: local variables have no impact on that. Any program unit calling that would be happy with an implicit interface. What you are asking about is how the two local arrays can be used.

这在很大程度上归结为两个数组的用途.

This largely comes down to what uses the two arrays can be put to.

如果第二个过程的虚拟参数具有 allocatable 属性,那么只有这里的可分配数组可以传递给该过程.它还需要有一个显式接口.无论程序是否更改分配,都是如此.

If the dummy argument of a second procedure has the allocatable attribute then only the allocatable array here can be passed to that procedure. It will also need to have an explicit interface. This is true whether or not the procedure changes the allocation.

当然,两个数组都可以作为参数传递给没有 allocatable 属性的虚拟参数,这样我们就没有不同的接口要求.

Of course, both arrays could be passed as arguments to a dummy argument without the allocatable attribute and then we don't have different interface requirements.

无论如何,当分配状态等没有变化时,为什么要将参数传递给可分配的虚拟对象?有充分的理由:

Anyway, why would one want to pass an argument to an allocatable dummy when there will be no change in allocation status, etc.? There are good reasons:

  • 过程中可能有一个代码路径确实发生了分配更改(例如由开关控制);
  • 可分配的虚拟参数也可以传递边界;
  • 等,

如果子程序有规范,这第二个更明显

This second one is more obvious if the subroutine had specification

subroutine mysub(n)
integer, intent(in)  :: n
integer              :: automatic_array(2:n+1)
integer, allocatable :: alloc_array(:)

allocate(alloc_array(2:n+1))

最后,自动对象对其大小有相当严格的条件.n 这里显然是允许的,但在分配成为唯一可行的方法之前,事情不必复杂得多.取决于人们想要玩多少 block 构造.

Finally, an automatic object has quite strict conditions on its size. n here is clearly allowed, but things don't have to be much more complicated before allocation is the only plausible way. Depending on how much one wants to play with block constructs.

还从 IanH 获得评论:如果我们有一个非常大的 n 自动对象可能会导致崩溃和烧毁.使用 allocatable,可以使用 stat= 选项与编译器运行时达成某种友好的协议.

Taking also a comment from IanH: if we have a very large n the automatic object is likely to lead to crash-and-burn. With the allocatable, one could use the stat= option to come to some amicable agreement with the compiler run-time.

这篇关于本地可分配数组和自动数组的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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