2017-01-18 16 views
2

Я скомпилировал ту же программу для разных флагов оптимизации: -O0, -O1, -O2 и -O3. Я использовал gcc и icc. Ниже вы можете увидеть фрагмент файла make:Как возможно, двоичный файл не изменяется при увеличении флага оптимизации?

build-gcc-O3: CXX = g++ 
build-gcc-O3: BIN_POST_NAME = -gcc-O3 
build-gcc-O3: OPT_FLAGS = -O3 
build-gcc-O3: fluidsGL 

build-icc-O0: CXX = $(INTEL_ICPC) 
build-icc-O0: BIN_POST_NAME = -icc-O0 
build-icc-O0: OPT_FLAGS = -O0 
build-icc-O0: fluidsGL 

fluidsGL: fluidsGL.o fluidsGL_cpu.o bilinear_interpolation.o defines.o 
    $(CXX) $(CXXFLAGS) $(BINARY_DIR)/defines.o $(BINARY_DIR)/bilinear_interpolation.o $(BINARY_DIR)/fluidsGL_cpu.o $(BINARY_DIR)/fluidsGL.o -o $(BINARY_DIR)/[email protected]$(BIN_POST_NAME)$(DBG_NAME_APPEND) $(OPT_FLAGS) -lGL -lGLU -lGLEW -lglut -lfftw3f 

После запуска make результат выглядит нормально. Так, например, это делают команды результирующей для ICC с -O3:

"/opt/intel/compilers_and_libraries/linux/bin/intel64/icpc" -Wall bin/defines.o bin/bilinear_interpolation.o bin/fluidsGL_cpu.o bin/fluidsGL.o -o bin/fluidsGL-icc-O3 -O3 -lGL -lGLU -lGLEW -lglut -lfftw3f 

После компиляции, fluidsGL-GCC-O0 и fluidsGL-GCC-O3 (и fluidsGL-ICC-O0 против fluidsGL-ICC-О3) двоичных файлов нужно то же самое место на диске, это уже кажется странным для меня:

$ ls -la bin/ 
total 728 
drwxrwxr-x 3 jesus jesus 4096 ene 18 09:56 . 
drwxrwxr-x 7 jesus jesus 4096 ene 18 09:31 .. 
-rw-rw-r-- 1 jesus jesus 4200 ene 18 09:56 bilinear_interpolation.o 
-rw-rw-r-- 1 jesus jesus 5608 ene 18 09:56 defines.o 
-rw-rw-r-- 1 jesus jesus 14952 ene 18 09:56 fluidsGL_cpu.o 
-rwxrwxr-x 1 jesus jesus 30780 ene 18 09:56 fluidsGL-gcc-O0 
-rwxrwxr-x 1 jesus jesus 43940 ene 18 09:56 fluidsGL-gcc-O0-dbg 
-rwxrwxr-x 1 jesus jesus 44272 ene 18 09:56 fluidsGL-gcc-O0-dbg-gprof 
-rwxrwxr-x 1 jesus jesus 30780 ene 18 09:56 fluidsGL-gcc-O1 
-rwxrwxr-x 1 jesus jesus 30780 ene 18 09:56 fluidsGL-gcc-O2 
-rwxrwxr-x 1 jesus jesus 30780 ene 18 09:56 fluidsGL-gcc-O3 
-rwxrwxr-x 1 jesus jesus 71151 ene 18 09:56 fluidsGL-icc-O0 
-rwxrwxr-x 1 jesus jesus 71151 ene 18 09:56 fluidsGL-icc-O1 
-rwxrwxr-x 1 jesus jesus 71151 ene 18 09:56 fluidsGL-icc-O2 
-rwxrwxr-x 1 jesus jesus 71151 ene 18 09:56 fluidsGL-icc-O3 
-rw-rw-r-- 1 jesus jesus 34664 ene 18 09:56 fluidsGL.o 

Но даже после того, как с помощью диф для сравнения файлов не отображается выход, а это означает, что двоичные файлы такие же точные бинарные файлы:

$ diff bin/fluidsGL-gcc-O0 bin/fluidsGL-gcc-O3 
$ diff bin/fluidsGL-icc-O0 bin/fluidsGL-icc-O3 
$ 

Является ли это нормальным поведением компилятора или я делаю ошибку здания?

+1

Какой код? Может быть, это слишком просто? –

+3

Вы попробовали перекомпилировать? Я знаю, что проблема при переходе от отладки к компиляции профилей, которая делает, принимает только изменения исходного кода, а не изменения makefile/compilerflags, чтобы определить, нужно ли перекомпилировать исходный файл. –

+0

@ KirilKirov Код довольно сложный, это процессорный порт моделирования стабильной жидкости CUDA, где я выполняю адвекции, диффузии, проекции. Я использую OpenGL для отображения движения частиц на холсте. Математический фон можно прочитать здесь: http://http.developer.nvidia.com/GPUGems/gpugems_ch38.html –

ответ

5

Флаги -Ox (где x - уровень оптимизации) предназначены для оптимизации компилятора, но вы на самом деле не перекомпилируете. Вы просто перевязываете уже скомпилированный объект (.o).

Обязательно добавьте флаг -Ox в команды компиляции для объектных файлов и выполните полную очистку.

3

Это скорее всего ошибка сборки .... или вы ожидаете, что make-файл будет производить перестройку, несмотря на то, что не настроил ее на это.

Файлы объектов обычно могут быть связаны друг с другом, даже если они построены с использованием различных параметров оптимизации. Таким образом, make обычно не удаляет объектные файлы или не восстанавливает их просто потому, что вы указали изменение настройки оптимизации.

Если вы наблюдаете за ходом сборки, вы, вероятно, увидите, что вторая сборка не выполняет перекомпиляции или перезагрузки.

Настройте что-то вроде цели clean в файле makefile, который удаляет скомпилированные объекты (* .o) и исполняемые файлы. И сделайте make clean между двумя сборками, которые вы хотите сравнить (после того, как вы сохраните исполняемый файл, конечно, иначе вы не сможете их сравнить).

Возможно, что ваш код настолько прост, что он не пользуется изменением настроек оптимизации. Но я в этом сомневаюсь.