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.