tl; dr: Я обнаружил, что запись «подразумеваемая do» была медленнее, чем явная при определенных обстоятельствах, и хочу понять, почему/если я могу улучшить это.Fortran подразумевает do write speedup
Детали:
У меня есть код, который делает что-то эффект:
DO i=1,n
calculations...
!m, x, and y all change each pass through the loop
IF(m.GT.1)THEN
DO j=1,m
WRITE(10,*)x(j),y(j) !where 10 is an output file
ENDDO
ENDIF
ENDDO
Выходной файл заканчивает тем, что довольно большой, и поэтому кажется, что написание большой коэффициент производительности, поэтому я хотел его оптимизировать. Прежде чем кто-либо спросит, нет, переход от ASCII не является вариантом из-за различных требований к нисходящему потоку. Соответственно, я переписал IF
заявление (и содержание) как:
IF(m.GT.1)THEN
!build format statement for write
WRITE(mm1,*)m-1
mm1=ADJUSTL(mm1)
!implied do write statement
WRITE(10,'('//TRIM(mm1)//'(i9,1x,f7.5/),i9,1x,f7.5)')(x(j),y(j),j=1,m)
ELSEIF(m.EQ.1)THEN
WRITE(10,'(i9,1x,f7.5)')x(1),y(1)
ENDIF
Это создает формат оператора в соответствии с # значений должны быть выписаны, а затем делает один оператор записи для вывода вещей. Я обнаружил, что этот код на самом деле работает медленнее с этой формулировкой. Для справки я видел значительное ускорение в одной и той же системе (аппаратное и программное обеспечение) при переходе к подразумеваемой инструкции do write, когда количество данных, которые должны быть записаны, было исправлено. В предположении, что сам оператор WRITE
работает быстрее, тогда это означало бы накладные расходы из пары строк, строящих это утверждение, что занимает дополнительное время, но это кажется трудным поверить. Для справки, m
может варьироваться в зависимости от суммы, но, вероятно, в среднем составляет не менее 1000. Является ли конкатенация строк //
очень медленным оператором, или есть что-то еще, что мне не хватает? Заранее спасибо.
Что делать, если вы просто используете 'write (10, '(i9, f8.5)') (...)' и полагаетесь на реверсию формата? – francescalus
Ore использует '*' как множитель или просто любое большое число, например 999999. –
Фактический формат вывода имеет еще несколько значений, так что '*' может привести к нежелательной обертке строк. Но я понятия не имел, что подход francescalus не указывать, а VladimirF просто использовать число, которое всегда больше, чем 'm', были допустимыми параметрами. Я попробую их и обновить. – TTT