Я намагався зачистити цю сторінку з GCC, але все одно не зрозумів, насправді.
Яка різниця між -march
та -mtune
?
Коли один використовує справедливий -march
, проти обох? Чи можливо це просто -mtune
?
Відповіді:
Якщо ви використовуєте, -march
тоді GCC зможе генерувати інструкції, які працюють на вказаному ЦП, але (як правило) не на попередніх ЦП із сімейства архітектур.
Якщо ви просто використовуєте -mtune
, то компілятор створить код, який працює на будь-якому з них, але надасть перевагу послідовностям інструкцій, які найшвидше працюють на конкретному вказаному вами процесорі. наприклад, встановити евристику розгортання циклу відповідно до цього процесора.
-march=foo
передбачає, -mtune=foo
якщо ви також не вказали інше -mtune
. Це одна з причин, чому використовувати -march
краще, ніж просто вмикати такі опції, як -mavx
нічого не робити з налаштуванням.
Застереження: -march=native
на центральному процесорі, який GCC спеціально не розпізнає, все одно ввімкне нові набори команд, які GCC може виявити, але залишить -mtune=generic
. Використовуйте достатньо новий GCC, який знає про ваш процесор, якщо ви хочете, щоб він створив хороший код.
march
означає mtune
. Отже, відповіді на ваші заперечення, відповідно, ні та так.
mtune
та march
комбіновані. Цей допис у блозі висвітлює це питання разом з іншими: lemire.me/blog/2018/07/25/…
Ось що я погуглив:
-march=X
Опція бере ім'я процесора X
і дозволяє GCC генерувати код , який використовує всі можливості X
. Посібник GCC пояснює, які саме імена центральних процесорів означають, які сімейства та функції процесорів.
Оскільки функції зазвичай додаються, але не видаляються, двійковий файл, побудований з, -march=X
буде працювати на центральному процесорі X
, має великі шанси працювати на центральних процесорах, новіших ніж X
, але майже не буде працювати на чомусь старшому X
. Деякі набори команд (3DNow !, я думаю?) Можуть бути специфічними для певного постачальника процесора, і використання цих даних, ймовірно, дасть вам двійкові файли, які не працюють на конкуруючих ЦП, новіших чи інших.
-mtune=Y
Опція налаштовує згенерований код для запуску швидше , Y
ніж на інших процесорах він може працювати на. -march=X
передбачає -mtune=X
. -mtune=Y
не перевизначить -march=X
, тому, наприклад, мабуть, немає сенсу -march=core2
і -mtune=i686
- ваш код не буде працювати на чомусь старшому, ніж у core2
будь-якому випадку, через -march=core2
, то чому на Землі ви хочете оптимізувати для чогось старшого (менш функціонального), ніж core2? -march=core2 -mtune=haswell
має більше сенсу: не використовуйте жодних функцій, що перевищують те, що core2
надає (а це набагато більше, ніж те, що -march=i686
дає вам!), але оптимізуйте код для набагато новіших haswell
ЦП, а не для core2
.
Є також -mtune=generic
. generic
змушує GCC створювати код, який найкраще працює на поточних процесорах (значення generic
змін від однієї версії GCC до іншої). На форумах Gentoo ходять чутки, що -march=X -mtune=generic
код виробляється швидше, X
ніж код, що виробляється -march=X -mtune=X
(або просто -march=X
, як -mtune=X
мається на увазі). Не уявляю, правда це чи ні.
Як правило, якщо ви точно не знаєте, що вам потрібно, здається, що найкращий курс - це вказати -march=<oldest CPU you want to run on>
і -mtune=generic
( -mtune=generic
тут для протидії імпліцитному -mtune=<oldest CPU you want to run on>
, оскільки ви, мабуть, не хочете оптимізувати для найстарішого процесора). Або просто -march=native
, якщо ви коли-небудь будете працювати лише на тій самій машині, на якій ви будуєте.
-march=native
, можливо, ви захочете вказати -mtune=X
, тому що за замовчуванням все ще залишається -mtune=generic
, як було обговорено тут: lemire.me/blog/2018/07/25/…
-march=native
означає, що tune=native
добре, якщо ви використовуєте GCC, який знає про ваш процесор. У цій статті представлено лише поганий випадок. Новіші версії GCC покращують кодування загалом, особливо при використанні нових інструкцій, таких як AVX2 та AVX-512. І наявність налаштувань налаштування (наприклад, евристика розгортання циклу), розроблених для вашого процесора, є безперечним плюсом. Отже, якщо ви досить дбаєте про продуктивність, щоб використовувати ці параметри, використовуйте новий GCC, принаймні той, який знає про ваш процесор, бажано поточний стабільний випуск.
tune=generic
для нового члена тієї ж родини мікроархітектур, особливо щось на зразок озера Кабі, яке буквально ідентично мікроархітектурно Skylake. Але я думаю, що у нього все ще є інша сім'я / степпінг, тому GCC, який знав лише про Skylake та старші, міг не визнати його для налаштування.