Наскільки краще насправді компілятори Fortran?


74

Це питання є продовженням двох дискусій, які нещодавно з'явилися у відповідях на " C ++ проти Fortran для HPC ". І це трохи більше виклику, ніж питання ...

Один з найбільш часто почутих аргументів на користь Fortran - це те, що компілятори просто кращі. Оскільки більшість компіляторів C / Fortran мають один і той же зворотній кінець, код, сформований для семантично еквівалентних програм на обох мовах, повинен бути однаковим. Однак можна стверджувати, що компілятору C / Fortran є більш / менш легше оптимізувати.

Тому я вирішив спробувати простий тест: я дістав копію daxpy.f та daxpy.c і склав їх з gfortran / gcc.

Тепер daxpy.c - це лише переклад f2c на daxpy.f (автоматично генерований код, некрасивий, як чорт), тому я взяв цей код і трохи очистив його (зустріч daxpy_c), що в основному означало перезапис внутрішньої петлі як

for ( i = 0 ; i < n ; i++ )
    dy[i] += da * dx[i];

Нарешті, я повторно написав це (введіть daxpy_cvec), використовуючи векторний синтаксис gcc:

#define vector(elcount, type)  __attribute__((vector_size((elcount)*sizeof(type)))) type
vector(2,double) va = { da , da }, *vx, *vy;

vx = (void *)dx; vy = (void *)dy;
for ( i = 0 ; i < (n/2 & ~1) ; i += 2 ) {
    vy[i] += va * vx[i];
    vy[i+1] += va * vx[i+1];
    }
for ( i = n & ~3 ; i < n ; i++ )
    dy[i] += da * dx[i];

Зауважте, що я використовую вектори довжиною 2 (це все, що дозволяє SSE2), і я обробляю два вектори одночасно. Це тому, що в багатьох архітектурах у нас може бути більше одиниць множення, ніж у векторних елементів.

Усі коди були складені за допомогою gfortran / gcc версії 4.5 із прапорами "-O3 -Wall -msse2 -march = native -ffast-math -fomit-frame-pointer -malign-double -fstrict-aliasing". На своєму ноутбуці (процесор Intel Core i5, M560, 2.67GHz) я отримав такий вихід:

pedro@laika:~/work/fvsc$ ./test 1000000 10000
timing 1000000 runs with a vector of length 10000.
daxpy_f took 8156.7 ms.
daxpy_f2c took 10568.1 ms.
daxpy_c took 7912.8 ms.
daxpy_cvec took 5670.8 ms.

Таким чином, оригінальний код Fortran займає трохи більше 8,1 секунди, автоматичний переклад його займає 10,5 секунд, наївне реалізація C робить це за 7,9, а явно векторизований код робить це за 5,6, незначно менше.

Це Фортран трохи повільніше, ніж наївне реалізація С, і на 50% повільніше, ніж векторизована реалізація С.

Отже, ось питання: я рідний програміст на C, і тому я впевнений, що я зробив хорошу роботу над цим кодом, але код Fortran востаннє торкнувся в 1993 році і тому може бути трохи застарілим. Оскільки я не відчуваю себе комфортним кодуванням у Fortran, як інші, може хтось може зробити кращу роботу, тобто більш конкурентоспроможну порівняно з будь-якою з двох версій C?

Також хто-небудь може спробувати цей тест з icc / ifort? Векторний синтаксис, ймовірно, не спрацює, але мені було б цікаво побачити, як там поводиться наївна версія C. Те саме стосується тих, хто лежить навколо xlc / xlf.

Я завантажив вихідні коди і Makefile тут . Щоб отримати точні таймінги, встановіть CPU_TPS у test.c на кількість Гц на вашому процесорі. Якщо ви знайдете якісь вдосконалення будь-якої з версій, будь ласка, опублікуйте їх тут!

Оновлення:

Я додав тестовий код Stali до файлів в Інтернеті та доповнив його версією C. Я змінив програми, щоб робити петлі 1'000'000 на векторах довжиною 10'000, щоб відповідати попередньому тесту (і тому, що мій апарат не міг виділити вектори довжиною 1'000'000'000, як у оригіналі Сталі код). Оскільки цифри зараз трохи менші, я використав варіант, -par-threshold:50щоб зробити компілятор більшою ймовірністю паралелізації. Використовувана версія icc / ifort - 12.1.2 20111128, і результати такі

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=1 time ./icctest_c
3.27user 0.00system 0:03.27elapsed 99%CPU

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=1 time ./icctest_f
3.29user 0.00system 0:03.29elapsed 99%CPU

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=2 time ./icctest_c
4.89user 0.00system 0:02.60elapsed 188%CPU

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=2 time ./icctest_f
4.91user 0.00system 0:02.60elapsed 188%CPU

Підсумовуючи це, результати, з усіх практичних цілей, однакові як для версії C, так і для Fortran, і обидва коди паралельно здійснюються паралельно. Зауважте, що швидкі часи порівняно з попереднім випробуванням зумовлені використанням арифметики з одноточною плаваючою точкою!

Оновлення:

Хоча мені не дуже подобається, куди йде тягар доказів, я перекодував приклад множення матриці Сталі в C і додав його до файлів в Інтернеті . Ось результати потрійного циклу для одного та двох процесорів:

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=1 time ./mm_test_f 2500
 triple do time   3.46421700000000     
3.63user 0.06system 0:03.70elapsed 99%CPU

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=1 time ./mm_test_c 2500
triple do time 3.431997791385768
3.58user 0.10system 0:03.69elapsed 99%CPU

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=2 time ./mm_test_f 2500
 triple do time   5.09631900000000     
5.26user 0.06system 0:02.81elapsed 189%CPU

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=2 time ./mm_test_c 2500
triple do time 2.298916975280899
4.78user 0.08system 0:02.62elapsed 184%CPU

Зауважте, що cpu_timeу вимірювальних приладах Fortran час процесора, а не час настінного годинника, тому я завершив дзвінки, timeщоб порівняти їх для 2 процесорів. Ніякої різниці між результатами немає, за винятком того, що версія C робить трохи краще на двох ядрах.

Тепер для matmulкоманди, звичайно , тільки в Fortran в цьому власному не доступний в C:

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=1 time ./mm_test_f 2500
 matmul    time   23.6494780000000     
23.80user 0.08system 0:23.91elapsed 99%CPU

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=2 time ./mm_test_f 2500
 matmul    time   26.6176640000000     
26.75user 0.10system 0:13.62elapsed 197%CPU

Ого. Це абсолютно жахливо. Чи може хтось дізнатись, що я роблю не так, або пояснити, чому це внутрішнє все ще якось добре?

Я не додавав dgemmвиклики до еталону, оскільки це дзвінки в бібліотеку до тієї ж функції в Intel MKL.

Чи може хтось запропонувати для майбутніх тестів приклад, який, як відомо, у C повільніше, ніж у Фортран?

Оновлення

Для перевірки твердження Сталі про те, що matmulвнутрішній "на порядок магніту" швидше, ніж явний матричний добуток на менших матрицях, я змінив власний код на множення матриць розміром 100x100 за допомогою обох методів, 10 000 разів у кожній. Результати на одному та двох процесорах такі:

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=1 time ./mm_test_f 10000 100
 matmul    time   3.61222500000000     
 triple do time   3.54022200000000     
7.15user 0.00system 0:07.16elapsed 99%CPU

pedro@laika:~/work/fvsc$ OMP_NUM_THREADS=2 time ./mm_test_f 10000 100
 matmul    time   4.54428400000000     
 triple do time   4.31626900000000     
8.86user 0.00system 0:04.60elapsed 192%CPU

Оновлення

Grisu вірно вказує, що без оптимізацій gcc перетворює операції над складними номерами у виклики функцій бібліотеки, тоді як gfortran накреслює їх у кількох інструкціях.

Компілятор C генерує той самий, компактний код, якщо параметр -fcx-limited-rangeвстановлений, тобто компілятору доручено ігнорувати потенційні перевищення / недоліки в проміжних значеннях. Цей параметр якимось чином встановлений за замовчуванням у gfortran і може призвести до неправильних результатів. Примушування -fno-cx-limited-rangeв gfortran нічого не змінило.

Таким чином, це насправді аргумент проти використання gfortran для чисельних обчислень: Операції над складними значеннями можуть перевищувати / недолічувати, навіть якщо правильні результати знаходяться в діапазоні з плаваючою комою. Це насправді стандарт Fortran. У gcc або загалом у C99 за замовчуванням робиться все строго (читайте сумісність IEEE-754), якщо не вказано інше.

Нагадування: Будь ласка, майте на увазі, що головне питання полягав у тому, чи компілятори Fortran виробляють кращий код, ніж компілятори C. Це не місце для дискусій щодо загальних достоїнств однієї мови перед іншою. Мені б дуже цікаво, якщо хтось може знайти спосіб угамування gfortran для отримання дакпі настільки ефективний, як той на C, використовуючи явну векторизацію, оскільки це ілюструє проблеми необхідності покладатися на компілятор виключно для оптимізації SIMD або випадок, коли компілятор Fortran виходить зі свого аналога C.


Одне питання в тому, що якщо ваш процесор виконує частотний / турбо режим, ці результати можуть бути по всій карті.
Білл Барт

1
Зараз ваш daxpy_c.c оновлює x з кратним x і зовсім не торкається y. Ви можете виправити це, щоб зробити це справедливим ...
Джек Поульсон

1
@JackPoulson: Хороший улов, виправлений та оновлений результати.
Педро

2
Також я цілком впевнений, що різниця повністю пов'язана з ручним розкручуванням у версії Fortran, що плутає компілятор. Коли я замінюю його тим самим простим циклом, який ви помістили у свою версію C, продуктивність між цими двома практично однакова. Без змін версія Fortran пройшла повільніше з компіляторами Intel.
Джек Поульсон

1
@permeakra: Насправді стандарт C99 визначає restrictключове слово, яке точно повідомляє компілятору: припустити, що масив не збігається з будь-якою іншою структурою даних.
Педро

Відповіді:


37

Різниця у ваших таймінгах, мабуть, пов’язана з ручним розкручуванням дакпі-фортету Fortran . Наступні синхросигнали проходять на 2,67 ГГц Xeon X5650 за допомогою команди

./test 1000000 10000

Компілятори Intel 11.1

Fortran з ручним розкручуванням: 8,7 сек.
Fortran без ручного розкручування: 5,8 сек. З
ручним розкручуванням: 5,8 сек

Компілятори GNU 4.1.2

Фортран з ручним розкручуванням: 8,3 сек.
Фортран без ручної розмотки: 13,5 сек. З
ручним розкручуванням: 13,6 сек.
С векторними атрибутами: 5,8 сек.

Компілятори GNU 4.4.5

Фортран з ручним розмотуванням: 8,1 сек.
Фортран без ручного розкручування: 7,4 сек. З
ручним розкручуванням: 8,5 с.
С з векторним надрукуванням: 5,8 сек.

Висновки

  • Розгортання вручну допомогло компіляторам GNU 4.1.2 Fortran щодо цієї архітектури, але шкодить новій версії (4.4.5) та компілятору Intel Fortran.
  • Компілятор GNU 4.4.5 C значно конкурентоспроможніший від Fortran, ніж для версії 4.2.1.
  • Векторні характеристики дозволяють GCC продуктивності відповідати компіляторам Intel.

Час перевірити складніші процедури, такі як dgemv і dgemm?


Дякуємо за результати! Яку версію gcc ви використовували та чи можете ви бути трохи більш конкретними щодо процесора?
Педро

2
Ваш компілятор старший, ніж ваш процесор ... Чи можете ви спробувати з gcc-4.5?
Педро

1
Я просто спробував це. Векторизована версія GCC 4.4.5 точно відповідає результатам Intel 11.1.
Джек Поульсон

1
Щойно я встановив gcc / gfortran версії 4.4.5 і не можу відтворити відмінності без розгортання. Насправді, у асемблері, створеному для обох випадків, внутрішній цикл ідентичний, за винятком використаних імен регістрів, які є взаємозамінними. Чи можете ви повторно запустити тести, щоб бути впевненим?
Педро

4
Чи можемо ми сказати, що такий спосіб вирішує вікові дискусії: "ми продовжуємо використовувати фортран, тому що він більш ефективний", щоб ми могли нарешті кинути його у смітник?
Стефано Борині

16

Я запізнююсь на цю вечірку, тому мені важко слідкувати за всіма зверху. Питання велике, і я думаю, що якщо ви зацікавлені, його можна розбити на більш дрібні шматки. Одне, що мене зацікавило, - це просто ефективність ваших daxpyваріантів, а також те, чи Фортран повільніший, ніж C у цьому дуже простому коді.

Працюючи як на моєму ноутбуці (Macbook Pro, Intel Core i7, 2,66 ГГц), відносна продуктивність вашої ручної векторизованої версії C та не ручної векторизованої версії Fortran залежить від використовуваного компілятора (з вашими власними параметрами):

Compiler     Fortran time     C time
GCC 4.6.1    5408.5 ms        5424.0 ms
GCC 4.5.3    7889.2 ms        5532.3 ms
GCC 4.4.6    7735.2 ms        5468.7 ms

Отже, просто здається, що GCC покращився у векторизації циклу в гілці 4.6, ніж це було раніше.


В цілому дискусії, я думаю, що можна досить швидко написати та оптимізувати код як у C, так і у Fortran, майже так само, як у мові акта. Я зазначу, однак, одне: подібно до того, як асемблер писати складніше, ніж C, але дає точніший контроль над тим, що виконується процесором, C є більш низьким рівнем, ніж Fortran. Таким чином, він надає вам більше контролю над деталями, що може допомогти оптимізувати, де стандартний синтаксис Fortran (або його розширення постачальника) може не мати функціональних можливостей. Один випадок - це явне використання векторних типів, інший - можливість визначення ручного вирівнювання змінних, чого Фортран не здатний.


Ласкаво просимо до scicomp! Я погоджуюсь, що версії компілятора настільки ж важливі, як і мова в цьому випадку. Ви в своєму останньому реченні мали на увазі "з" замість "вимкнено"?
Арон Ахмадія

9

Те, як я написав AXPY у Fortran, дещо відрізняється. Це точний переклад математики.

m_blas.f90

 module blas

   interface axpy
     module procedure saxpy,daxpy
   end interface

 contains

   subroutine daxpy(x,y,a)
     implicit none
     real(8) :: x(:),y(:),a
     y=a*x+y
   end subroutine daxpy

   subroutine saxpy(x,y,a)
     implicit none
     real(4) :: x(:),y(:),a
     y=a*x+y
   end subroutine saxpy

 end module blas

Тепер назвемо вищевказану процедуру в програмі.

тест.f90

 program main

   use blas
   implicit none

   real(4), allocatable :: x(:),y(:)
   real(4) :: a
   integer :: n

   n=1000000000
   allocate(x(n),y(n))
   x=1.0
   y=2.0
   a=5.0
   call axpy(x,y,a)
   deallocate(x,y)

 end program main

Тепер давайте компілюємо і запускаємо його ...

login1$ ifort -fast -parallel m_blas.f90 test.f90
ipo: remark #11000: performing multi-file optimizations
ipo: remark #11005: generating object file /tmp/ipo_iforttdqZSA.o

login1$ export OMP_NUM_THREADS=1
login1$ time ./a.out 
real    0 m 4.697 s
user    0 m 1.972 s
sys     0 m 2.548 s

login1$ export OMP_NUM_THREADS=2
login1$ time ./a.out 
real    0 m 2.657 s
user    0 m 2.060 s
sys     0 m 2.744 s

Зауважте, що я не використовую циклів або явних директив OpenMP . Чи це можливо в C (тобто використання циклів і автоматична паралелізація)? Я не використовую C, тому не знаю.


Автоматична паралелізація - це особливість компіляторів Intel (і Fortran, і C), а не мова. Значить, еквівалент у С також повинен паралелізуватися. Щойно з цікавості, як це працює для більш помірного n = 10000?
Педро

3
В цьому і полягала вся суть. Autopar у Fortran легший через те, що Fortran (на відміну від C) підтримує цілі масиви операцій, такі як matmult, транспонирование і т. Д. Тож оптимізація коду простіша для компіляторів Fortran. GFortran (який ви використовували) не має ресурсів розробника для оптимізації компілятора Fortran, оскільки в даний час їхня увага спрямована на реалізацію стандарту Fortran 2003, а не на оптимізацію.
stali

Гмм ... Компілятор Intel C / C ++ iccтакож робить автоматичну паралелізацію. Я додав файл icctest.cдо інших джерел. Чи можете ви скласти його з тими ж параметрами, що й раніше, запустити його та повідомити про хронометри? Мені довелося додати printf-заяву до свого коду, щоб уникнути оптимізації гкч усе. Це просто швидкий злом, і я сподіваюся, що він не працює!
Педро

Я завантажив останні компілятори icc / ifort і сам зробив тести. Питання було оновлено, щоб включити ці нові результати, тобто автовекторизація Intel працює як у Fortran, так і в C.
Педро

1
Дякую. Так, я помітив, що різниця є мало, можливо, тому, що петлі прості, а операції - рівень 1 BLAS. Але, як я вже говорив раніше, завдяки здатності Fortran виконувати цілі операції з масивом та використовувати такі ключові слова, як PURE / ELEMENTAL, є більше місця для оптимізації компілятора. Як компілятори використовують цю інформацію і що вона насправді робить, це різна річ. Ви також можете спробувати matmul якщо ви хочете bpaste.net/show/23035
Staļi

6

Я думаю, не лише цікаво, як компілятор оптимізує код для сучасного обладнання. Особливо між GNU C та GNU Fortran покоління коду може бути дуже різним.

Тож розглянемо ще один приклад, щоб показати відмінності між ними.

Використовуючи складні числа, компілятор GNU C виробляє великі накладні витрати для майже дуже основної арифметичної операції над складним числом. Компілятор Fortran дає набагато кращий код. Давайте подивимось на наступний невеликий приклад у Fortran:

COMPLEX*16 A,B,C
C=A*B

дає (gfortran -g -o complex.fo -c complex.f95; objdump -d -S complex.fo):

C=A*B
  52:   dd 45 e0                fldl   -0x20(%ebp)
  55:   dd 45 e8                fldl   -0x18(%ebp)
  58:   dd 45 d0                fldl   -0x30(%ebp)
  5b:   dd 45 d8                fldl   -0x28(%ebp)
  5e:   d9 c3                   fld    %st(3)
  60:   d8 ca                   fmul   %st(2),%st
  62:   d9 c3                   fld    %st(3)
  64:   d8 ca                   fmul   %st(2),%st
  66:   d9 ca                   fxch   %st(2)
  68:   de cd                   fmulp  %st,%st(5)
  6a:   d9 ca                   fxch   %st(2)
  6c:   de cb                   fmulp  %st,%st(3)
  6e:   de e9                   fsubrp %st,%st(1)
  70:   d9 c9                   fxch   %st(1)
  72:   de c2                   faddp  %st,%st(2)
  74:   dd 5d c0                fstpl  -0x40(%ebp)
  77:   dd 5d c8                fstpl  -0x38(%ebp)

Які 39 байт машинного коду. Коли ми вважаємо те саме в С

 double complex a,b,c; 
 c=a*b; 

і подивившись на результат (зроблений так само, як вище), ми отримаємо:

  41:   8d 45 b8                lea    -0x48(%ebp),%eax
  44:   dd 5c 24 1c             fstpl  0x1c(%esp)
  48:   dd 5c 24 14             fstpl  0x14(%esp)
  4c:   dd 5c 24 0c             fstpl  0xc(%esp)
  50:   dd 5c 24 04             fstpl  0x4(%esp)
  54:   89 04 24                mov    %eax,(%esp)
  57:   e8 fc ff ff ff          call   58 <main+0x58>
  5c:   83 ec 04                sub    $0x4,%esp
  5f:   dd 45 b8                fldl   -0x48(%ebp)
  62:   dd 5d c8                fstpl  -0x38(%ebp)
  65:   dd 45 c0                fldl   -0x40(%ebp)
  68:   dd 5d d0                fstpl  -0x30(%ebp)

Має також 39 байт машинного коду, але посилається на етап 57, виконує належну частину роботи та виконує потрібну операцію. Таким чином, у нас є 27-байтний машинний код для запуску мульти операції. Функція muldc3, надана компанією, libgcc_s.soмає розмір 1375 байт у машинному коді. Це різко уповільнює код і дає цікавий вихід при використанні профілера.

Коли ми реалізуємо наведені вище приклади BLAS для zaxpyта виконуємо той же тест, компілятор Fortran повинен дати кращі результати, ніж компілятор C.

(Я використовував GCC 4.4.3 для цього експерименту, але я помітив цю поведінку в інших випусках GCC.)

Отже, на мій погляд, ми не думаємо лише про паралелізацію та векторизацію, коли думаємо про те, який кращий компілятор, ми також повинні дивитись, як базові речі переводяться на код асемблера. Якщо цей переклад дає поганий код, оптимізація може використовувати ці речі лише як вхідні дані.


1
Я щойно підготував приклад у відповідь на ваш код complex.cі додав його до коду в Інтернеті. Мені довелося додати весь вхід / вихід, щоб переконатися, що нічого не оптимізовано. Я дзвоню, лише __muldc3якщо не користуюся -ffast-math. З -O2 -ffast-mathмене я отримую 9 рядків вбудованого асемблера. Ви можете це підтвердити?
Педро

Я знайшов більш конкретну причину різниці в створеному асемблері і додав це до свого питання вище.
Педро

Використовуючи -O2 привести компілятор для обчислення всього, що можливо під час виконання, тому такі конструкції іноді втрачаються. Параметр -ffast-math не повинен використовуватися в наукових обчисленнях, коли ви хочете покластися на результати.
МК aka Grisu

1
Ну, за цим аргументом (ні -ffast-math) ви не повинні використовувати Fortran для своїх складних обчислень. Як я описую в оновленні свого запитання, -ffast-mathабо, загалом, -fcx-limited-rangeзмушує gcc використовувати ті ж обчислення з обмеженим діапазоном, що не IEEE, як стандартні у Fortran. Тож якщо ви хочете повний спектр складних значень та правильних Infs та NaNs, вам не слід використовувати Fortran ...
Педро,

2
@Pedro: Якщо ви хочете, щоб GCC поводився як GFortran Wrt. складне множення і ділення, ви повинні використовувати -fcx-fortran-правила.
janneb

4

Люди,

Я вважав цю дискусію дуже цікавою, але мене здивувало, що переупорядкування циклів у прикладі Matmul змінило картину. У мене немає компілятора Intel на моїй поточній машині, тому я використовую gfortran, але переписую петлі в mm_test.f90 до

call cpu_time(start)  
do r=1,runs  
  mat_c=0.0d0  
     do j=1,n  
        do k=1,n  
  do i=1,n  
           mat_c(i,j)=mat_c(i,j)+mat_a(i,k)*mat_b(k,j)  
        end do  
     end do  
  end do  
end do  
call cpu_time(finish)  

змінив усі результати для моєї машини.

Результати часу попередньої версії були:

#time ./mm_test_f 10000 100
 matmul    time   6.3620000000000001     
 triple do time   21.420999999999999     

тоді як з потрійними петлями, переставленими так, як викладено вище:

#time ./mm_test_f 10000 100
 matmul    time   6.3929999999999998     
 triple do time   3.9190000000000005    

Це gcc / gfortran 4.7.2 20121109 на Intel (R) Core (TM) i7-2600K CPU @ 3,40 ГГц

Прапорці компілятора, які використовувались, були такими з Makefile, який я потрапив сюди ...


3
Це не дивно, оскільки зберігання матриць у пам'яті надає перевагу одному порядку, тобто, якщо рядки зберігаються безперервно, краще перебирати рядки всередину, оскільки тоді ви можете один раз завантажити кожен рядок у швидку локальну пам'ять порівняно з багаторазовим завантаженням (фрагмент ) це доступ до одного елемента. Дивіться stackoverflow.com/questions/7395556 .
Крістіан Класон

Напевно, я був здивований, що "внутрішній матмул" не буде закодований робити такі речі. Це значно швидше, якщо потрійне впорядкування впорядковано другим способом. Здається, це є в цьому наборі компіляторів, оскільки попередні версії gfortran, до яких я можу потрапити, були більш "плоскими" в їх термінах - неважливо, яким чином ви зробили мульти - це зайняло майже той самий час.
Schatzi

-2

Це не швидкість роботи коду, хоча вони допомагають. Швидше запускаються коди саме компілятор, процесор і операційна система. Порівнювати мови - це просто неправильне, марне та безглузде. Це не має сенсу, оскільки ви порівнюєте дві змінні: мову та компілятор. Якщо один код працює швидше, ви не знаєте, наскільки це мова або скільки він є компілятором. Я не розумію, чому спільнота інформатики просто цього не розуміє :-(

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.