Fortran 使用函数扩展和普通do循环之间的执行时间差异

Fortran 使用函数扩展和普通do循环之间的执行时间差异,fortran,Fortran,我想研究普通do循环和函数扩展之间的执行时间差异。我要求每个方法重复地用相同的短数组填充长数组。下文显示了用于此目的的代码。但是,我一直收到一条错误消息,指示存在堆栈溢出。有人能告诉我我的代码有什么问题吗?谢谢 背风 编辑添加:嗯,我明白了为什么我的程序不起作用(在我的桌面上,使用Visual Studio 2012中的Intel Visual Fortran 2013)。这个错误是由于我没有取消分配其中一个阵列造成的 在我将long\u-ray添加到代码片段中未包含的行中:解除分配(int\u

我想研究普通do循环和函数扩展之间的执行时间差异。我要求每个方法重复地用相同的短数组填充长数组。下文显示了用于此目的的代码。但是,我一直收到一条错误消息,指示存在堆栈溢出。有人能告诉我我的代码有什么问题吗?谢谢

背风

编辑添加:嗯,我明白了为什么我的程序不起作用(在我的桌面上,使用Visual Studio 2012中的Intel Visual Fortran 2013)。这个错误是由于我没有取消分配其中一个阵列造成的

在我将long\u-ray添加到代码片段中未包含的行中:解除分配(int\u-array、short\u-array、box\u-ray)之后,程序终于运行了


顺便说一下,我发现,当long1的大小不超过10^8时,第一个代码块(普通do循环)的执行时间远短于函数扩展块的执行时间。我可以说do循环在重新填充长序列方面优于SPREAD吗?

您的程序溢出了堆栈,因为您没有足够的堆栈空间

编译器通常将与表达式计算关联的临时对象放在堆栈上。在您的程序中有许多这样的表达式,包括紧接着allocate之后的数组构造函数,以及稍后的spread和reforme引用。给定
long1
的值和整数的典型大小,某些表达式可能需要~0.4 GB的堆栈空间。这是很多,特别是相对于一个只有1MB的主要平台上的默认堆栈大小限制

如果您减小
long1
的大小,并确保您的程序具有足够的堆栈分配,那么您的代码片段对我来说是可行的


编辑添加:请注意,聪明的优化人员可能会注意到正在定义的数组没有被使用,因此不必费心执行定义它们的代码。

您的程序溢出了堆栈,因为您没有足够的堆栈空间

编译器通常将与表达式计算关联的临时对象放在堆栈上。在您的程序中有许多这样的表达式,包括紧接着allocate之后的数组构造函数,以及稍后的spread和reforme引用。给定
long1
的值和整数的典型大小,某些表达式可能需要~0.4 GB的堆栈空间。这是很多,特别是相对于一个只有1MB的主要平台上的默认堆栈大小限制

如果您减小
long1
的大小,并确保您的程序具有足够的堆栈分配,那么您的代码片段对我来说是可行的


编辑添加:请注意,聪明的优化人员可能会注意到正在定义的数组没有被使用,因此不必费心执行定义它们的代码。

您的程序溢出了堆栈,因为您没有足够的堆栈空间

编译器通常将与表达式计算关联的临时对象放在堆栈上。在您的程序中有许多这样的表达式,包括紧接着allocate之后的数组构造函数,以及稍后的spread和reforme引用。给定
long1
的值和整数的典型大小,某些表达式可能需要~0.4 GB的堆栈空间。这是很多,特别是相对于一个只有1MB的主要平台上的默认堆栈大小限制

如果您减小
long1
的大小,并确保您的程序具有足够的堆栈分配,那么您的代码片段对我来说是可行的


编辑添加:请注意,聪明的优化人员可能会注意到正在定义的数组没有被使用,因此不必费心执行定义它们的代码。

您的程序溢出了堆栈,因为您没有足够的堆栈空间

编译器通常将与表达式计算关联的临时对象放在堆栈上。在您的程序中有许多这样的表达式,包括紧接着allocate之后的数组构造函数,以及稍后的spread和reforme引用。给定
long1
的值和整数的典型大小,某些表达式可能需要~0.4 GB的堆栈空间。这是很多,特别是相对于一个只有1MB的主要平台上的默认堆栈大小限制

如果您减小
long1
的大小,并确保您的程序具有足够的堆栈分配,那么您的代码片段对我来说是可行的


编辑添加:请注意,聪明的优化人员可能会注意到正在定义的数组没有被使用,因此不必费心执行定义它们的代码。

该程序在gfortran中对我有效,但在Intel Fortran中不起作用。您可以使用
-heap arrays n
强制ifort在堆上分配数组,其中
n
是以kB为单位的限制。我使用
200
。它可以使一些计算速度变慢,您可以尝试测量。

该程序在gfortran中对我有效,但在Intel Fortran中无效。您可以使用
-heap arrays n
强制ifort在堆上分配数组,其中
n
是以kB为单位的限制。我使用
200
。它可以使一些计算速度变慢,您可以尝试测量。

该程序在gfortran中对我有效,但在Intel Fortran中无效。您可以使用
-heap arrays n
强制ifort在堆上分配数组,其中
n
是以kB为单位的限制。我使用
200
。它可以使一些计算速度变慢,您可以尝试测量。

该程序在gfortran中对我有效,但在Intel Fortran中无效。您可以使用
-heap arrays n
强制ifort在堆上分配数组,其中
n
是以kB为单位的限制。我使用
200
。这会使一些计算速度变慢,你必须尝试一下
... 
integer, dimension(:), allocatable :: long_ray,short_ray 
integer, dimension(:,:), allocatable :: box_ray          
integer :: i, long1, short1
long1 = 100000000
short1 = 100

allocate(long_ray(long1),short_ray(short1),box_ray(short1,long1/short1))
long_ray = [((i),i=1,long1)]
short_ray = [((i),i=1,short1)]
call system_clock(t1)
do i = 1,long1/short1
    long_ray((i-1)*short1+1:i*short1) = short_ray(:)
enddo
call system_clock(t2)
print*,'1 time: ',t2-t1

call system_clock(t1)
box_ray = spread(short_ray,2,long1/short1)
long_ray = reshape(box_ray, shape(long_ray))
call system_clock(t2)
print*,'2 time: ',t2-t1  
...