GCC: чим марш відрізняється від mtune?


88

Я намагався зачистити цю сторінку з GCC, але все одно не зрозумів, насправді.

Яка різниця між -marchта -mtune?

Коли один використовує справедливий -march, проти обох? Чи можливо це просто -mtune?

Відповіді:


97

Якщо ви використовуєте, -marchтоді GCC зможе генерувати інструкції, які працюють на вказаному ЦП, але (як правило) не на попередніх ЦП із сімейства архітектур.

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


-march=fooпередбачає, -mtune=fooякщо ви також не вказали інше -mtune. Це одна з причин, чому використовувати -marchкраще, ніж просто вмикати такі опції, як -mavxнічого не робити з налаштуванням.

Застереження: -march=nativeна центральному процесорі, який GCC спеціально не розпізнає, все одно ввімкне нові набори команд, які GCC може виявити, але залишить -mtune=generic. Використовуйте достатньо новий GCC, який знає про ваш процесор, якщо ви хочете, щоб він створив хороший код.


10
Не відповідає, чи є сенс використовувати обидва, чи mtune зайвий, якщо встановлено одне і те ж значення.
Павло Шимерда,

12
@ PavelŠimerda Інтуїтивно відповідь передбачається у визначенні 2-х ознак. Крім того, в документації прямо зазначено, що це marchозначає mtune. Отже, відповіді на ваші заперечення, відповідно, ні та так.
underscore_d

Дякую, що ви так елегантно пояснили це! Ви спрощуєте його розуміння.
Рахім Ходжа,

5
Людям потрібен tl; dr: Використовуйте -march, якщо ви ТІЛЬКИ запускаєте його на своєму процесорі, використовуйте -mtune, якщо хочете, щоб він був безпечним для інших процесорів.
j riv

3
Користувачі також повинні розуміти, що старі компілятори (випущені до того, як якийсь процесор не існував) можуть спричинити різні оптимальні mtuneта marchкомбіновані. Цей допис у блозі висвітлює це питання разом з іншими: lemire.me/blog/2018/07/25/…
qneill

52

Ось що я погуглив:

-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, якщо ви коли-небудь будете працювати лише на тій самій машині, на якій ви будуєте.


4
Але якщо ви використовуєте -march=native, можливо, ви захочете вказати -mtune=X, тому що за замовчуванням все ще залишається -mtune=generic, як було обговорено тут: lemire.me/blog/2018/07/25/…
Роланд Вебер,

@RolandWeber: Це трапляється лише в тому випадку, якщо ви використовуєте GCC занадто старий, щоб знати про ваш процесор. -march=nativeозначає, що tune=nativeдобре, якщо ви використовуєте GCC, який знає про ваш процесор. У цій статті представлено лише поганий випадок. Новіші версії GCC покращують кодування загалом, особливо при використанні нових інструкцій, таких як AVX2 та AVX-512. І наявність налаштувань налаштування (наприклад, евристика розгортання циклу), розроблених для вашого процесора, є безперечним плюсом. Отже, якщо ви досить дбаєте про продуктивність, щоб використовувати ці параметри, використовуйте новий GCC, принаймні той, який знає про ваш процесор, бажано поточний стабільний випуск.
Пітер Кордес,

Це жахливо, що GCC не може зробити нічого кращого, ніж tune=genericдля нового члена тієї ж родини мікроархітектур, особливо щось на зразок озера Кабі, яке буквально ідентично мікроархітектурно Skylake. Але я думаю, що у нього все ще є інша сім'я / степпінг, тому GCC, який знав лише про Skylake та старші, міг не визнати його для налаштування.
Пітер Кордес,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.