g ++ O1 не равен O0 со всеми связанными флагами оптимизации - PullRequest
0 голосов
/ 06 ноября 2018

Я знаю, что название немного сбивает с толку. Позвольте мне прояснить мою проблему с небольшим фоном:

Моя программа ведет себя странно, когда я компилирую ее с флагом -O1 против -O0 с точки зрения времени выполнения. Я знаю, что флаг -O1 выполняет много оптимизаций, таких как fauto-inc-dec -fbranch-count-reg -fcombine-stack-adjustments (более 40 в соответствии с man-страницей). Чтобы выяснить, какие оптимизации вызывают такое поведение, я планирую удалять флаги по одному, а затем компилировать и тестировать, чтобы что-то изменить.

Перед проведением этого эксперимента я хочу убедиться, что программа, скомпилированная с -O1, и программа, скомпилированная с -O0, плюс все флаги, которые разрешает -O1 (позволяет вызывать -O0+), ведут себя аналогично. На самом деле, я ожидаю, что оба метода должны создавать один и тот же двоичный файл, поскольку включены одинаковые флаги оптимизации.

Компиляция с O1

CC = g++

CFLAGS = -std=c++11 -Wall -fopenmp
SOURCE = a_count_f.cpp
EXEC = run
INC = inc

all: $(EXEC)
.PHONY: all

$(EXEC): $(SOURCE)
    $(CC) $(CFLAGS) -O1 -o $(EXEC) -I$(INC) $^

Компиляция с O0+

CC = g++

CFLAGS = -std=c++11 -Wall -fopenmp
SOURCE = a_count_f.cpp
EXEC = run
INC = inc

OPT_FLAGS = -fauto-inc-dec -fbranch-count-reg -fcombine-stack-adjustments -fcompare-elim -fcprop-registers -fdce -fdefer-pop -ftree-builtin-call-dce -fdse -fforward-propagate -fguess-branch-probability -fif-conversion2 -fif-conversion -finline-functions-called-once -fipa-pure-const -fipa-profile -fipa-reference -fmerge-constants -fmove-loop-invariants -fomit-frame-pointer -freorder-blocks -fshrink-wrap -fshrink-wrap-separate -fsplit-wide-types -fssa-backprop -fssa-phiopt -ftree-bit-ccp -ftree-ccp -ftree-ch -ftree-coalesce-vars -ftree-copy-prop -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-phiprop -ftree-scev-cprop -ftree-sink -ftree-slsr -ftree-sra -ftree-pta -ftree-ter -funit-at-a-time

all: $(EXEC)
.PHONY: all

$(EXEC): $(SOURCE)
    $(CC) $(CFLAGS) -O0 $(OPT_FLAGS) -o $(EXEC) -I$(INC) $^

Однако оказалось, что -O1 и -O0+ дают совершенно разные результаты. Несмотря на все различия в оптимизации, -O0 и -O0+ дают очень похожие результаты. (Под результатами я подразумеваю время выполнения)

Я проверил обе компиляции с помощью -Q --help=optimizers, и вывод подтвердил, что оба активируют одинаковые флаги.

Следующим для меня является сравнение ассемблерных кодов. Прежде чем сделать это, я хочу спросить здесь, есть ли у кого-нибудь идея, почему это происходит. Я не включил исходный код, так как кажется, что проблема не связана с исходным кодом. Но я могу прикрепить его при необходимости.

g ++ версия: g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

1 Ответ

0 голосов
/ 06 ноября 2018

Флаги оптимизации, применяемые -O1, применяются только при включенном оптимизаторе. Вам нужно указать -On с помощью n > 0, чтобы флаги оптимизации действительно что-либо делали.

Другими словами, -O0 не включает оптимизатор, поэтому флаги оптимизации ничего не делают.


Вы можете отключить флаги оптимизации, используя форму флага -fno. Например,

-fcompare-elim 

флаг включается -O1, и вы можете выключить его, используя

-fno-compare-elim 

Еще одна вещь, на которую следует обратить внимание, как отмечает TC , - это то, что не у всех оптимизаций есть флаг , поэтому нет никакого способа отключить эти конкретные оптимизации.

...