Как посмотреть, какие флаги -march = native активируют?

165

Я компилирую свое приложение C ++, используя GCC 4.3. Вместо того, чтобы вручную выбирать флаги оптимизации, которые я использую -march=native, теоретически следует добавить все флаги оптимизации, применимые к оборудованию, на котором я компилирую. Но как я могу проверить, какие флаги он использует?

Vartec
источник

Ответы:

150

Вы можете использовать -Q --help=targetпараметры:

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

-vВариант может также использоваться.

Вы можете увидеть документацию по --helpопции здесь .

thkala
источник
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-dirty) это приведет к возвращаемой ошибке: Сообщения ассемблера: Ошибка: неизвестная собственная архитектура Ошибка: нераспознанная опция -march = native. Так, освободят , -march=nativeи он будет работать везде только следующее: gcc -Q --help=target.
Олег Кокорин
@Oleg - это звучит как ошибка в GCC 5. Вопрос не присутствует в НКУ 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'
42n4
источник
10

Если вы хотите узнать, как настроить не нативную кросс-компиляцию, я нашел это полезным:

На целевой машине

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

Затем используйте это на сборочной машине:

% gcc -march=core-avx-i ...
Марк Лаката
источник
Это не будет включать все флаги, к сожалению.
Креститель, который
@BaptisteWicht есть ли флаги, которые -march = native будут включать то, что -march = core-avx-i не будет, в этом случае, или какие флаги? Спасибо!
rogerdpack
2
@rogerdpack На этом компьютере (sandybridge) march = sandybridge не включает AVX (не знаю почему), а march = native делает. Еще одно важное отличие состоит в том, что размеры кэша извлекаются только с помощью 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, до которого это просто нераспознанный аргумент.

Даниэль Сантос
источник
Хорошо, у этого gleans также есть размеры кэша
rogerdpack
gcc версии 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) возвращает: Ошибка: неизвестная «родная» архитектура
Олег Кокорин
Олег: Какую арку вы используете? Вполне возможно, что «родной» поддерживается только на некоторых архитектурах.
Даниэль Сантос