Подтвердить что ты не робот

Почему библиотека gcc math настолько неэффективна?

Когда я переносил некоторый код fortran на c, он удивил меня тем, что большая часть несоответствия времени выполнения между программой fortran, скомпилированной с ifort (intel fortran compiler) и c-программой, скомпилированной с gcc, исходит из оценок тригонометрических функции (sin, cos). Это меня удивило, потому что я верил в то, что объясняет этот , что функции, такие как синус и косинус, реализованы в микрокоде внутри микропроцессоров.

Чтобы выявить проблему более явно, я сделал небольшую тестовую программу в fortran

program ftest
  implicit none
  real(8) :: x
  integer :: i
  x = 0d0
  do i = 1, 10000000
    x = cos (2d0 * x)
  end do
  write (*,*) x
end program ftest

В процессоре intel Q6600 и 3.6.9-1-ARCH x86_64 Linux Я получаю с ifort version 12.1.0

$ ifort -o ftest ftest.f90 
$ time ./ftest
  -0.211417093282753     

real    0m0.280s
user    0m0.273s
sys     0m0.003s

а при gcc version 4.7.2 я получаю

$ gfortran -o ftest ftest.f90 
$ time ./ftest
  0.16184945593939115     

real    0m2.148s
user    0m2.090s
sys     0m0.003s

Это почти различие в 10 раз! Могу ли я по-прежнему полагать, что реализация gcc cos является оболочкой реализации микропроцессора так же, как это, вероятно, сделано в реализации Intel? Если это правда, где находится горло бутылки?

ИЗМЕНИТЬ

Согласно комментариям, включенные оптимизации должны повысить производительность. Мое мнение заключалось в том, что оптимизация не влияет на функции библиотеки... что не означает, что я не использую их в нетривиальных программах. Однако, вот два дополнительных теста (теперь на моем домашнем компьютере intel core2)

$ gfortran -o ftest ftest.f90
$ time ./ftest
  0.16184945593939115     

real    0m2.993s
user    0m2.986s
sys     0m0.000s

и

$ gfortran -Ofast -march=native -o ftest ftest.f90
$ time ./ftest
  0.16184945593939115     

real    0m2.967s
user    0m2.960s
sys     0m0.003s

Какие конкретные оптимизации вы имели в виду (комментаторы)? И как компилятор может использовать многоядерный процессор в этом конкретном примере, где каждая итерация зависит от результата предыдущего?

РЕДАКТИРОВАТЬ 2

Базовые тесты Даниэля Фишера и Илмари Каронена заставили меня подумать, что проблема может быть связана с конкретной версией gcc (4.7.2) и, возможно, с конкретной сборкой (Arch x86_64 Linux), которую я использую мои компьютеры. Поэтому я повторил тест в поле intel core i7 с debian x86_64 Linux, gcc version 4.4.5 и ifort version 12.1.0

$ gfortran -O3 -o ftest ftest.f90
$ time ./ftest
  0.16184945593939115     

real    0m0.272s
user    0m0.268s
sys     0m0.004s

и

$ ifort -O3 -o ftest ftest.f90
$ time ./ftest
  -0.211417093282753     

real    0m0.178s
user    0m0.176s
sys     0m0.004s

Для меня это очень приемлемая разница в производительности, которая никогда не заставит меня задавать этот вопрос. Кажется, что я должен буду спросить на форумах Arch Linux об этой проблеме.

Однако объяснение всей истории по-прежнему очень приветствуется.

4b9b3361

Ответ 1

Большая часть этого объясняется различиями в математической библиотеке. Некоторые моменты, которые следует учитывать:

  • Да, процессоры x86 с модулем x87 имеют команды fsin и fcos. Однако они реализованы в микрокоде, и нет особых причин, по которым они должны быть быстрее, чем чистая реализация программного обеспечения.
  • GCC не имеет собственной математической библиотеки, а использует только предоставленную систему. В Linux это обычно обеспечивается glibc.
  • 32-разрядный x86 glibc использует fsin/fcos.
  • x86_64 glibc использует программные реализации с использованием блока SSE2. Долгое время это было намного медленнее, чем 32-разрядная версия glibc, которая использовала только инструкции x87. Тем не менее, улучшения (в последнее время) были сделаны, поэтому в зависимости от того, какая версия glibc у вас будет, может быть, не так плохо, как раньше.
  • Набор компиляторов Intel благословлен ОЧЕНЬ быстрой математической библиотекой (libimf). Кроме того, он включает в себя векторизованные трансцендентальные математические функции, которые часто могут ускорить цикл с помощью этих функций.