#fortran #sleep #gfortran #intel-fortran
#fortran #сон #gfortran #intel-fortran
Вопрос:
Я проводил несколько тестов с приведенным ниже кодом, когда столкнулся со странным поведением в своей программе. Когда я использую вызов встроенной подпрограммы «sleep» в моей программе, в файл testing.dat ничего не было записано. Если я удалил вызов для этой подпрограммы, она работала нормально, цифры были записаны. Я попробовал тот же код (вызывающий подпрограмму «sleep») с Intel Fortran, и он также отлично работал.
Мне кажется, что подпрограмма sleep в некотором смысле останавливает выполнение до того, как файл будет записан с помощью программы, скомпилированной с использованием gfortran, поведение, которое не происходит с использованием Intel fortran. Я не эксперт в области компьютерных наук, но это мое предположение, у кого-нибудь еще есть лучший вариант? Я пробовал со всеми приведенными ниже флагами, и ничего не изменилось:
исполняемый файл gfortran -g file.f90 -o
исполняемый файл gfortran file.f90 -o
исполняемый файл gfortran -O3.f90 -o
Я использую ОС xubuntu 18.01.
program test
implicit none
integer :: i, j, k
open(34, file="testing.dat")
do i=1,9999999
do j=1,9999999
do k=1,9999999
print*, i, j, k
write(34,'(3I8)') i, j, k
call sleep (1)
end do
end do
end do
end program
Комментарии:
1. Вы нигде не закрываете файл. Используйте
close(34)
. Вы действительно планируете ждать 999999700000029999999 секунд? Это будет очень долгое ожидание. Имейте в виду, что данные могут быть видны в файле только после некоторой буферизации. Сначала попробуйте меньший объем данных, 9x9x9 должно быть достаточно. Вы также можете попробоватьflush(34)
.2. Вы говорите, что код компилируется и отлично работает с Intel. В году примерно 31536000 секунд. Итак, если программа переходит в спящий режим, для завершения потребуется 3.17e13 лет. Что означает «работает нормально»?
3. Что касается времени запуска программы, я просто проводил некоторые эксперименты с использованием gdb (я изучаю его). Я не ожидал, что он будет работать все это время. Под нормальной работой с Intel fortran я подразумеваю, что он записал числа в файл до завершения работы программы (я остановил его с помощью Ctrl c), в то время как с gfortran этого не происходит. Я уменьшил объем данных до 2x2x2, и он записал числа даже с помощью gfortran. Конечный результат для меня заключается в том, что если я использую gdb для отладки любой программы, которая сочетает команды sleep и write, я могу получить пустые файлы до окончания выполнения.
4. Используя flush(34), программа, скомпилированная с помощью gfortran, записала в файл во время выполнения, как я и ожидал. Я не знал эту функцию. Спасибо @VladimirF
5. gfortran буферизует свои выходные данные. Вы можете управлять этим с помощью переменных среды, которые описаны в руководстве. Смотрите GFORTRAN_UNBUFFERED_ALL.
Ответ №1:
Вывод файла может быть буферизован. Это означает, что символы или байты, которые должны быть записаны во внешний файл, сначала собираются где-то в памяти, а затем записываются во внешний файл большими порциями. Это может ускорить вывод файла. Если вы случайно посмотрите на внешний файл, он не обязательно должен содержать выходные данные всех write
выполненных операторов, некоторые могут быть в буферах. flush(unit)
Оператор делает данные видимыми для внешних процессов, удаляя данные. Руководство по gfortran для более старых flush
внутренних состояний подпрограммы
Встроенная функция FLUSH и инструкция FLUSH Fortran 2003 имеют идентичный эффект: они очищают буфер ввода-вывода библиотеки времени выполнения, так что данные становятся видимыми для других процессов. Это не гарантирует, что данные будут сохранены на диске.
Буферизацией файла также обычно можно управлять настройками компилятора или библиотеки времени выполнения с использованием флагов компилятора или переменных среды. Для gfortran вы можете найти переменные среды выполнения по адресуhttps://gcc.gnu.org/onlinedocs/gfortran/Runtime.html#Runtime
Есть четыре переменные, которые могут вас заинтересовать:
GFORTRAN_UNBUFFERED_ALL
: Не буферизовать ввод-вывод для всех устройств
GFORTRAN_UNBUFFERED_PRECONNECTED
: Не буферизуйте ввод-вывод для предварительно подключенных устройств.
GFORTRAN_FORMATTED_BUFFER_SIZE
: Размер буфера для форматированных файлов
GFORTRAN_UNFORMATTED_BUFFER_SIZE
: Размер буфера для неформатированных файлов
Комментарии:
1. Обратите внимание, что даже после очистки данные могут находиться в других буферах или кэшах, управляемых ОС или встроенным программным обеспечением диска, и поэтому «Это не гарантирует, что данные будут сохранены на диске»..