Я компилирую свое приложение на С++ с помощью GCC 4.3. Вместо того, чтобы вручную выбирать флаги оптимизации, я использую -march=native
, который теоретически должен добавить все флаги оптимизации, применимые к аппаратным средствам, которые я компилирую. Но как я могу проверить, какие флаги используются на самом деле?
Как увидеть, какие флаги -march = native будут активированы?
Ответ 1
Вы можете использовать опции -Q --help=target
:
gcc -march=native -Q --help=target ...
Опция -v
также может быть полезна.
Вы можете увидеть документацию по опции --help
здесь.
Ответ 2
Чтобы увидеть флаги командной строки, используйте:
gcc -march=native -E -v - </dev/null 2>&1 | grep cc1
Если вы хотите увидеть, что компилятор/прекомпилятор задает определенные параметры, сделайте следующее:
echo | gcc -dM -E - -march=native
Ответ 3
Он должен быть (-###
похож на -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'
Ответ 4
Если вы хотите узнать, как настроить неродную кросс-компиляцию, я нашел это полезным:
На целевой машине
% gcc -march=native -Q --help=target | grep march
-march= core-avx-i
Затем используйте это на машине сборки:
% gcc -march=core-avx-i ...
Ответ 5
Я собираюсь бросить свои два цента в этот вопрос и предложить несколько более подробное расширение ответа elias. Начиная с 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), поэтому я предлагаю также запустить следующий script, чтобы убедиться, что все эти флаги -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, перед которым он является только непризнанным аргументом.
Ответ 6
Я написал скрипт, который будет выдавать список флагов, готовый для gcc -march=native -mtune=native -Q --help=target
обратно в gcc
из вывода gcc -march=native -mtune=native -Q --help=target
. Это немного грубо, не эффективно, но, кажется, делает свое дело.
Есть одна оговорка, о которой я знаю: опции со знаком равенства (=
) и никакими значениями удаляются намеренно.
gcc -march=native -mtune=native -Q --help=target -v 2>&1 \
| grep -h "The following options" -A200 -B0 \
| tail -n +2 \
| grep -h "Known assembler" -A0 -B999 \
| head -n -2 \
| grep -v "disabled" \
| sed -r 's/\[(enabled|default)\]//g'\
| sed -r 's/\s*//g' \
| sed -r 's/\=$//g' \
| sed -r 's/<.*>//g' \
| xargs
Вы можете удалить xargs
в конце, чтобы увидеть флаги построчно.