Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 按分配隐式分配与显式分配/解除分配_Fortran - Fatal编程技术网

Fortran 按分配隐式分配与显式分配/解除分配

Fortran 按分配隐式分配与显式分配/解除分配,fortran,Fortran,如果我的编译器符合Fortran 2003,我可以重新分配可分配变量或数组,而无需显式的取消分配/分配过程,如中所述。例如 integer, allocatable :: i(:) i = [1,2,3] i = [1,2,3,4,5] 与旧的(Fortran 90)方式相比: 这种新技术的优点和缺点是什么?它当然比旧的方式更简洁。但是有没有理由选择老办法呢?我在代码示例中仍然看到旧的方式比新的方式多得多,但可能这只是因为Fortran 90的使用率仍然高于Fortran 2003 作为一个

如果我的编译器符合Fortran 2003,我可以重新分配可分配变量或数组,而无需显式的取消分配/分配过程,如中所述。例如

integer, allocatable :: i(:)

i = [1,2,3]
i = [1,2,3,4,5]
与旧的(Fortran 90)方式相比:

这种新技术的优点和缺点是什么?它当然比旧的方式更简洁。但是有没有理由选择老办法呢?我在代码示例中仍然看到旧的方式比新的方式多得多,但可能这只是因为Fortran 90的使用率仍然高于Fortran 2003

作为一个快速计时检查,我在gfortran 4.8.5下循环了上面的代码100000000次,发现更新的方式似乎也更快,运行时间大约为4秒(新方式)而不是6秒(旧方式)。相反,在下面的注释中,@roygvib与gfortran 8.2的结果基本相反


另外,请注意这里最近对这个问题的讨论:

优点是代码简洁

integer, allocatable :: i(:)

i = [1, 2, 3]
比…少一行

integer, allocatable :: i(:)

allocate(i(3))
i = [1, 2, 3]
此外,您不需要显式地写入分配的大小,因此冗余信息少了一点

不方便的是,这是一个自动功能

我可以很容易地想到两种情况,其中特性是一个缺点

  • 数组
    i
    在分配时重新分配是有充分理由的(即代码中没有bug),并引入了可能更难发现的性能损失
  • 由于代码中存在逻辑错误,数组
    i
    被重新分配。如果由此导致的越界内存访问抛出segfault:-),则更容易检测到此错误

  • 不过,您可能会使用编译器检查来检测“2”,并使用探查器来解决“1”。所以,除非你有充分的理由不使用该功能,否则我会说“使用它”。然而,对于现有的代码库,没有特定的动机删除allocate语句“仅仅因为”。

    优点是代码简洁

    integer, allocatable :: i(:)
    
    i = [1, 2, 3]
    
    比…少一行

    integer, allocatable :: i(:)
    
    allocate(i(3))
    i = [1, 2, 3]
    
    此外,您不需要显式地写入分配的大小,因此冗余信息少了一点

    不方便的是,这是一个自动功能

    我可以很容易地想到两种情况,其中特性是一个缺点

  • 数组
    i
    在分配时重新分配是有充分理由的(即代码中没有bug),并引入了可能更难发现的性能损失
  • 由于代码中存在逻辑错误,数组
    i
    被重新分配。如果由此导致的越界内存访问抛出segfault:-),则更容易检测到此错误

  • 不过,您可能会使用编译器检查来检测“2”,并使用探查器来解决“1”。所以,除非你有充分的理由不使用该功能,否则我会说“使用它”。然而,对于现有的代码库,没有明确的动机来删除allocate语句“仅仅因为”。

    我将列出差异,什么是优点或缺点是主观的

    编译器必须检查每个完整数组赋值的正确界限-但无论如何都必须这样做,即使您不使用重新分配。除非在某些编译器中完全禁用此标准功能

    对于那些不习惯动态语言的人来说,大多数赋值都会进行一些分配,这可能是一个重要的事实,即在
    deallocate
    reallocate
    语句中,可以清楚地看到实际上正在发生重新分配


    通过自动重新分配,编译器可能会使用,特别是在
    a=[a,1]
    这样的情况下。但据我所知,编译器目前并没有这样做。然而,通常的
    malloc
    通常会重新使用旧数组所在的内存(如果它适合那里)。

    我将列出不同之处,优势和劣势是主观的

    编译器必须检查每个完整数组赋值的正确界限-但无论如何都必须这样做,即使您不使用重新分配。除非在某些编译器中完全禁用此标准功能

    对于那些不习惯动态语言的人来说,大多数赋值都会进行一些分配,这可能是一个重要的事实,即在
    deallocate
    reallocate
    语句中,可以清楚地看到实际上正在发生重新分配


    通过自动重新分配,编译器可能会使用,特别是在
    a=[a,1]
    这样的情况下。但据我所知,编译器目前并没有这样做。然而,通常的
    malloc
    通常会重复使用旧数组所在的内存,如果它适合那里的话。

    在重复问题中,更多类似的问题请参见右侧的链接。在这种情况下,您应该以这样的方式写问题,即清楚地说明非重复方面,如果添加的编辑仍然保留了其他地方解释的要点,请重新编写问题!好的,我是为你做的……其他问题似乎围绕着“我有一个bug”这个主题,而这个问题涉及两种编程风格之间的比较。@JohnE没有什么能阻止你改进问题,阻止你在问题关闭或“暂停”时改进问题。相反,关闭消息通常显式地包含使其重新打开所需的操作说明。唉,我自己做了这样一个编辑,然后重新打开了你的问题。我刚刚尝试比较了10^8个循环的上述两种模式,但是第二个版本比gfortran-8.2-O3更快(约40%)。另一方面,稍微旧一点的PGI fortran给出了基本相同的计时。因此,结果可能因编译器而异?在重复问题中,更多类似问题请参见右侧的链接。在这种情况下,您应该以这样一种方式编写问题,即清楚地说明非重复方面,而不是添加一个仍会留下错误的编辑