Да. Иногда я могу делать такие глупости, что через секунду я не могу понять, как это возможно ... Я ошибочно полагал, что генераторы случайных чисел имели примерно одинаковую производительность, но это, очевидно, не так. Я написал с нуля на обоих языках действительно простой конгруэнтный генератор, идентичный (просто перевод), ничего не использованный в контексте serius (и на самом деле «физические» результаты просто мусор), но я получаю те же результаты с точностью машины в C и в Fortran, но код на Fortran выполняется примерно на 25% быстрее. Я чувствую себя лучше. Еще раз спасибо.
исал (для моего класса по численным методам теоретической физики) очень простую программу для случайного блуждания в измерении 2. Вот оно:
program random_walk
implicit none
integer, parameter :: Nwalker = 1000000
integer, parameter :: Nstep = 100
integer, parameter :: Nmeas = 10
integer :: posx, posy, move
integer :: is, im, iw
real :: start_time, stop_time
double precision, dimension(Nmeas) :: dist, r2
real :: rnd
do im = 1, Nmeas
dist(im) = im*Nstep
r2(im) = 0.0
end do
call cpu_time(start_time)
do iw = 1, Nwalker
posx = 0
posy = 0
do im = 1, Nmeas
do is = 1, Nstep
call random_number(rnd)
move = 4*rnd
if (move == 0) posx = posx + 1
if (move == 1) posy = posy + 1
if (move == 2) posx = posx - 1
if (move == 3) posy = posy - 1
end do
r2(im) = r2(im) + posx**2 + posy**2
end do
end do
r2 = r2 / Nwalker
call cpu_time(stop_time)
do im = 1, Nmeas
print '(f8.6, " ", f8.6)', log(dist(im)), log(r2(im))
end do
print '("Time = ", f6.3, " seconds")', stop_time - start_time
end program
В конце должно быть напечатано 10 строк и 2 столбца: первый столбец - логарифм «времени» (количество шагов), второй столбец - логарифм среднего квадрата расстояния от начала координат. Второй столбец «в среднем» должен быть равен первому. Пока все хорошо, программа работает хорошо, результаты очень разумные. Но здесь проблема; на моем macbookpro (2,7 ГГц Intel Core i7, компилятор gfortran 7.1.0, оптимизация -O2) он работает в среднем более 20 секунд для запуска. Но если я закомментирую эти строки:
! do im = 1, Nmeas
! print '(f8.6, " ", f8.6)', log(dist(im)), log(r2(im))
! end do
которые находятся за пределами вычисления "stop_time", в результате время выполнения составляет ... менее 6 секунд !?
Как это возможно?