Фортран: 10 вложенных циклов медленные с завершением оператора печати

У меня есть некоторый код, который запускается примерно за секунду, но после очень незначительного редактирования замедляется.

Следующий код выполняется через 1 секунду с gfortran -O3

  program loop
          implicit none
          integer n, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10
          parameter(n=18) !<=== most important
          integer i,array(n)
          real cal
          real p1(n)

  do i=1,n
     p1(i)=float(i)/10.
  enddo

  write (*,1) p1

1 format (10(f6.2))

  cal=0.
  i1=0
  i2=0

  do i1=1,n
  !write(*,1) cal !<-- too slow if write here
     do i2=1,n
        do i3=1,n
           do i4=1,n
              do i5=1,n
                 do i6=1,n
                    do i7=1,n
                       do i8=1,n
                          do i9=1,n
                            do i10=1,n
     cal=p1(i1) !<-- perfectly happy to compute, as long as I don't write
     array(i1)=i1+i2
                            enddo
                          enddo
                       enddo
                    enddo
                 enddo
              enddo
           enddo
        enddo
     enddo
     !write(*,1) cal !<-- and too slow if write here too!
   enddo

   write(*,*) (array(i),i=1,n)

   stop
   end

Прежде всего, прости меня за смесь f77 и 90. Это пример, основанный на реальной проблеме. Однако существенным моментом является то, что если параметр n = 17, все в порядке. Второе-последнее оператор записи может быть некомментирован, и код выполняется примерно за секунду. Тем не менее, при n=18 код замедляется... если, если оператор записи со второго по последний закомментирован, он выполняется за секунду с n=18.

В двух тестах всего 17^10 и 18^10 итераций. Я не смог найти никаких указаний на ограничение количества итераций. Я продолжаю думать, что 18^10 должно превышать некоторый предел, но я не знаю, что. И почему утверждение print имеет значение для n=18, а не для n = 17? Больше информации: использование Mem близко к нулю. Процессор i5-4570, процессор с тактовой частотой 3,20 ГГц.

Если я использую -O0, код всегда работает очень медленно.

1 ответ

С gfortan 4.8.3 я не вижу большой разницы во времени выполнения write заявления и опуская их, но есть огромная разница между -O3 а также -O0, Причина этого в том, что компилятор может массово оптимизировать циклы с -O3с которым это не связано -O0, Компилятор может по существу выработать ответ заранее и полностью пропустить циклы. При более высоких оптимизациях компилятор также может использовать более сложные функции вашего ЦП, которые работают быстрее.

Ввод write Операторы внутри цикла несколько нарушают способность компилятора агрессивно оптимизировать циклы, а это означает, что он больше не может полностью их пропускать, что приводит к более медленным временам выполнения, которые вы видите. Вероятно, вы используете старую версию gfortran, которая не очень хорошо справляется с этой ситуацией.

Другие вопросы по тегам