Я знаю, что название немного сбивает с толку. Позвольте мне прояснить мою проблему с небольшим фоном:
Моя программа ведет себя странно, когда я компилирую ее с флагом -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