Як побачити, які прапори -march = native активуються?


165

Я складаю додаток C ++ за допомогою GCC 4.3. Замість того, щоб вручну вибирати використовувані прапори оптимізації -march=native, які теоретично повинні додавати всі прапори оптимізації, застосовні до обладнання, яке я компілюю. Але як я можу перевірити, які прапори він насправді використовує?

Відповіді:


150

Ви можете скористатися -Q --help=targetпараметрами:

gcc -march=native -Q --help=target ...

Цей -vваріант також може бути корисним.

Ви можете ознайомитись з документацією щодо --helpопції тут .


10
Я збираюся припустити, що це неоптимально. Вихід --help = target не відображає інформацію про кеш процесора, про яку наведені нижче методи і elias, і 42n4. Зокрема, на gcc 4.9.2 на Phenom, вихід включає такі:--param l1-cache-size=64 --param l1-cache-line-size=64 --param l2-cache-size=512
Даніель Сантос,

@DanielSantos: у моїй системі він відображає ці параметри з -vопцією, хоча у складі cc1командного рядка ...
thkala

не ідеальний. на gcc версії 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-брудний) це призведе до помилки у відповідь: Повідомлення ассемблера: Помилка: невідома архітектура рідка Помилка: нерозпізнаний варіант -march = native. Так, звільнять , -march=nativeі він буде працювати скрізь тільки наступне: gcc -Q --help=target.
Олег Кокорін

@Oleg - Це здається помилкою в GCC 5. Проблема відсутня в GCC 7.
jww

111

Щоб побачити прапори командного рядка, використовуйте:

gcc -march=native -E -v - </dev/null 2>&1 | grep cc1

Якщо ви хочете, щоб компілятор / прекомпілятор визначає встановлені за певними параметрами, зробіть це:

echo | gcc -dM -E - -march=native

1
Ця відповідь заслуговує стільки ж результатів, скільки прийнятих, зокрема, перелічення того, що nativeнасправді дорівнює.
Iwillnotexist Idonotexist

4
тож якщо я хотів би перехрестити нативну компіляцію, я повинен подавати обом компілятору обидва значення та аргументи? або аргументів достатньо?
hanshenrik

25

Це має бути ( -###схоже на -v):

echo | gcc -### -E - -march=native 

Показати "справжні" рідні прапори для gcc.

Ви можете зробити їх більш чіткими за допомогою команди:

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )//g'

і ви можете позбутися прапорів за допомогою -mno- * за допомогою:

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )|( -mno-[^\ ]+)//g'

10

Якщо ви хочете дізнатися, як налаштувати не-рідну перехресну компіляцію, я вважаю це корисним:

На цільовій машині

% gcc -march=native -Q --help=target | grep march
-march=                               core-avx-i

Потім використовуйте це на машині складання:

% gcc -march=core-avx-i ...

Це, на жаль, не включатиме всі прапори.
Батист Віхт

@BaptisteWicht чи існують прапори, які -march = native включатимуть, що -march = core-avx-я б не робив у цьому випадку чи які прапори? Дякую!
rogerdpack

2
@rogerdpack На цьому комп'ютері (піщаний міст), march = sandybridge не дозволяє AVX (не знаю чому), тоді як march = native. Ще одна важлива відмінність полягає в тому, що розміри кешу витягуються лише з маршу = нативної
Baptiste Wicht

1
@BaptisteWicht, що це дивно, здається, працює тут (я думаю): echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1але розміри кешу, здається, відсутні.
rogerdpack

7

Я збираюся кинути свої два центи на це питання і запропонувати трохи більш багатослівне розширення відповіді Іллі. Станом на gcc 4.6, запуску викидів gcc -march=native -v -E - < /dev/nullвипромінює все більше спаму у вигляді зайвих -mno-*прапорів. Далі буде знято наступне:

gcc -march=native -v -E - < /dev/null 2>&1 | grep cc1 | perl -pe 's/ -mno-\S+//g; s/^.* - //g;'

Однак я перевірив правильність цього лише на двох різних процесорах (Intel Core2 та AMD Phenom), тому пропоную також запустити наступний сценарій, щоб бути впевненим, що всі ці -mno-*прапори можна безпечно зняти.

#!/bin/bash

gcc_cmd="gcc"

# Optionally supply path to gcc as first argument
if (($#)); then
    gcc_cmd="$1"
fi

with_mno=$(
    "${gcc_cmd}" -march=native -mtune=native -v -E - < /dev/null 2>&1 |
    grep cc1 |
    perl -pe 's/^.* - //g;'
)
without_mno=$(echo "${with_mno}" | perl -pe 's/ -mno-\S+//g;')

"${gcc_cmd}" ${with_mno}    -dM -E - < /dev/null > /tmp/gcctest.a.$$
"${gcc_cmd}" ${without_mno} -dM -E - < /dev/null > /tmp/gcctest.b.$$

if diff -u /tmp/gcctest.{a,b}.$$; then
    echo "Safe to strip -mno-* options."
else
    echo
    echo "WARNING! Some -mno-* options are needed!"
    exit 1
fi

rm /tmp/gcctest.{a,b}.$$

Я не знайшов різниці між цими цими параметрами gcc -march=native -v -E - < /dev/nullта gcc -march=native -### -E - < /dev/nullіншими параметрами, які не містять спеціальних символів, тому я не впевнений, за яких обставин це має реальну зміну.

Нарешті, зауважте, що це --march=nativeбуло введено в gcc 4.2, перед яким це лише нерозпізнаний аргумент.


Приємно, що у цього блиску також розміри кешу
rogerdpack

gcc версія 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-брудний) повертається: Помилка: невідома архітектура `рідна '
Олег Кокорін

Олег: Яку арку ти використовуєш? Можливо, "рідний" підтримується лише в деяких архітектурах.
Даніель Сантос
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.