【发布时间】:2019-03-05 05:03:28
【问题描述】:
最近我正在研究访问 fortran 数组的复杂性。感谢 cmets,我在这里包含了完整的示例。
program main
implicit none
integer, parameter :: mp = SELECTED_REAL_KIND(15,307)
integer, parameter :: Np=10, rep=100
integer*8, parameter :: Ng(7) = (/1E3,1E4,1E5,1E6,1E7,1E8,1E9/)
real(mp), allocatable :: x(:)
real(mp) :: time1, time2
integer*8 :: i,j,k, Ngj
real(mp) :: temp
integer :: g
! print to screen
print *, 'calling program main'
do j=1,SIZE(Ng) !test with different Ng
!initialization with each Ng. Don't count for complexity.
Ngj = Ng(j)
if(ALLOCATED(x)) DEALLOCATE(x)
ALLOCATE(x(Ngj))
x = 0.0_mp
!!===This is the part I want to check the complexity===!!
call CPU_TIME(time1)
do k=1,rep
do i=1,Np
call RANDOM_NUMBER(temp)
g = floor( Ngj*temp ) + 1
x( g ) = x( g ) + 1.0_mp
end do
end do
call CPU_TIME(time2)
print *, 'Ng: ',Ngj,(time2-time1)/rep, '(sec)'
end do
! print to screen
print *, 'program main...done.'
contains
end program
一开始我认为它的复杂性是 O(Np)。但这是 Np=10 的时间测量:
calling program main
Ng: 1000 7.9000000000000080E-007 (sec)
Ng: 10000 4.6000000000000036E-007 (sec)
Ng: 100000 3.0999999999999777E-007 (sec)
Ng: 1000000 4.8000000000001171E-007 (sec)
Ng: 10000000 7.3999999999997682E-007 (sec)
Ng: 100000000 2.1479999999999832E-005 (sec)
Ng: 1000000000 4.5719999999995761E-005 (sec)
program main...done.
这种 Ng 依赖性非常缓慢,仅在非常大的 Ng 时出现,但在增加 Np 时不受支配;增加 Np 只是在该时间缩放上乘以一个常数因子。 此外,当我使用更复杂的子例程而不是随机数时,缩放斜率似乎会增加。 计算 temp 和 g 被证实与 Ng 无关。 这种情况有两个问题:
- 基于 cmets,这种测量不仅包括预期的算术运算,还包括与内存缓存或编译器相关的成本。是否有更正确的方法来衡量复杂性?
- 关于 cmets 中提到的问题,如内存缓存、页面丢失或编译器,它们是否随着数组大小的增加而不可避免?或者有什么办法可以避免这些费用?
【问题讨论】:
-
欢迎您,请拨打tour。您没有显示完整的代码,请参阅minimal reproducible example。您必须显示完整的代码,包括时间测量和编译器命令。编译器可能会优化您的代码,因为未使用结果。我们有重复的回合 stackoverflow.com/questions/47583729/…
-
也有可能我不明白你显示的数字是什么意思,也许是时候进行一次迭代了。但是您必须明确地说明这一点并用您的代码说明这一点!另见How to Ask。不要忘记不仅有 CPU,还有内存和缓存,访问它们会花费不同的时间。
-
VladimirF 几乎可以肯定是正确的,您会看到由于缓存和可能的页面未命中而导致的成本增加。但是恐怕如果没有完整程序的更清晰的解释,就不可能肯定地说。并且不要使用非标准的、潜在的不可移植的 real*8 - 使用您清楚知道的种类,因为您在常量上使用了 _dp
-
请记住,big-O 和渐近复杂度的整个结构是基于计算机的理论模型,其中涉及一些琐碎的问题,例如缓存大小、内存访问的时间一致性和一大堆其他的工程问题都被简单地假设了。观察到循环时间从
~0.0s到~0.0s,因为Ng经历了 3 个数量级,这告诉我们有关它正在运行的计算机的一些信息,而根本没有关于操作的复杂性顺序。跨度> -
@VladimirF 感谢 cmets。我只是用一个完整的例子代替。
标签: arrays fortran time-complexity