ist die g++ optimierung schlechter, wenn source auf mehreren files aufgeteilt ist



  • hallo,
    ich habe einen algorithmus in c++ geschrieben, der das TSP(traveling salesman problem) mittels simulated annealing "lösen" soll.

    der code funktioniert soweit auch recht gut, allerdings wenn ich ihn kompiliere, ist die laufzeit sehr stark abhängig davon, ob die files als object-files eingebungen wurden, oder ob der gesamte source in einem file ist.

    ich habe die klasse und ein paar funktionen in jeweils eigene .cpp und .h files ausgelagert.

    mein make file sieht so aus:

    DBGFLAGS=-g -O0
    PRODFLAGS=-O3
    CFLAGS=-std=c++11 -pedantic -Wall -pthread -lboost_program_options
    CC=g++
    SRC=./
    
    OBJECTFILES=${SRC}perm.o ${SRC}operations.o
    
    #$@...Name of the target
    #$^...a list of dependencies (without double entries)
    all: distances.h
    all: main
    all: comb
    
    dbg: distances.h
    dbg: maindbg
    
    main: ${SRC}main.o ${OBJECTFILES}
    	${CC} ${CFLAGS} ${PRODFLAGS} -o $@ $^
    
    comb: ${SRC}comb.cpp 
    	${CC} ${CFLAGS} ${PRODFLAGS} -o $@ $^
    
    maindbg: ${SRC}main.o ${OBJECTFILES}
    	${CC} ${CFLAGS} ${DBGFLAGS} -o $@ $^
    
    %.o: %.cpp
    	${CC} ${CFLAGS} ${DBGFLAGS} -c -o $@ $^
    
    distances.h: 
    	./gen_distances.pl
    
    clean:
    	rm -f main.o perm.o operations.o main maindbg distances.h comb
    

    das problem tritt auf, wenn ich "make all" aufrufe.

    comb.cpp und main.cpp enthalten jeweils den selben code, mit dem unterschied, dass er beim comb in einem file liegt und keine externen files eingebunden werden müssen und bei main.cpp ist alles in 2 externe files(perm.cpp und operations.cpp) ausgelagert.

    wenn ich comb aufrufe, ist das programm etwa 5x schneller, als mit main.

    ich denke, mein fehler müsste ja wohl nur eine konfiguration (parameter beim g++) sein, somit hab ich euch den source des programms nicht mitgegeben.

    sollte er dennoch benötigt werden, werd ich ihn gerne hochladen.

    danke schonmal



  • Kompiliere mal mit "-flto" (http://gcc.gnu.org/wiki/LinkTimeOptimization)



  • Ich hänge immer noch ein -Wextra dran, aber das sei dir überlassen.



  • dankeschön für den tipp, flto hat leider nix gebracht. sie sind beide exakt gleich. einmal mit und einmal ohne flto.
    (hatte zweimal 30sek) und das combined schaffts in 7sek

    das mit Wextra ist ja nur dass die warnungen als errors kommen, oder das ist ja für die performance egal? oder doch nicht?



  • Was passiert, wenn du statt dem makefile einen einzigen gcc Aufruf (-flto nicht vergessen) nutzt?



  • Jo, Wextra ist nur für Warnungen.

    Wenn ich mir dein Makefile genauer ansehe, stelle ich fest, dass du die *.o-Files mit Debug-Flags kompilierst. Dann ist natürlich schon zu spät, die mit Optimierungen zusammenzulinken.

    Mal so ungetestet zusammengehackt, wie das Makefile besser aussehen sollte:

    DBGFLAGS=-g -O0
    PRODFLAGS=-O3
    CFLAGS=-std=c++11 -pedantic -Wall -pthread -lboost_program_options
    
    ifdef DEBUG
    CFLAGS += $(DBGFLAGS)
    else
    CFLAGS += $(PRODFLAGS)
    endif
    
    CC=g++
    SRC=$(wildcard *.cc) # Viel bequemer
    OBJ=$(patsubst %.cc,%.o,$(SRC)) # und einfacher
    HDR=$(wildcard *.h) distances.h # Das geht besser, siehe http://www.c-plusplus.net/forum/88418-full
    
    all: main
    
    main: $(OBJ)
        $(CC) $(CFLAGS) $< -o $@
    
    $(OBJS): %.o: %.cc $(HDR)
        $(CC) $(CFLAGS) -c $< -o $@
    
    distances.h:
        ./gen_distances.pl
    
    clean:
        rm -f $(OBJ) distances.h main
    


  • danke, das war zwar nicht das problem, aber das hat mir geholfen, das problem zu finden:

    es muss natürlich so heißen:

    %.o: %.cpp
        ${CC} ${CFLAGS} ${PRODFLAGS} -c -o $@ $^
    

    und mit

    PRODFLAGS=-flto -O3
    

    gehts jetzt auch! dankeschön...

    eine sache wäre da noch:
    wie kann ich, wenn ich "make dbg" eingebe alle .cpp files mit DBGFLAGS kompileren?
    weil wenn ich jetzt "make dbg" eingebe, ist das .cpp file trotzdem im produktionsmodus oder?

    mein verbessertes makefile sieht jetzt so aus:

    DBGFLAGS=-g -O0 
    PRODFLAGS=-flto -O3 
    CFLAGS=-std=c++11 -pedantic -Wall -pthread
    CC=g++
    SRC=./
    
    OBJECTFILES=${SRC}perm.o ${SRC}operations.o
    
    #$@...Name of the target
    #$^...a list of dependencies (without double entries)
    all: distances.h
    all: main
    all: bsp7
    all: bsp4
    
    dbg: distances.h
    dbg: maindbg
    
    main: ${SRC}main.o ${OBJECTFILES}
        ${CC} ${CFLAGS} ${PRODFLAGS} -o $@ $^
    
    bsp7: ${SRC}bsp7.cpp
        ${CC} ${CFLAGS} ${PRODFLAGS} -o $@ $^
    
    bsp4: ${SRC}bsp4.cpp 
        ${CC} ${CFLAGS} ${PRODFLAGS} -o $@ $^
    
    maindbg: ${SRC}main.o ${OBJECTFILES}
        ${CC} ${CFLAGS} ${DBGFLAGS} -o $@ $^
    
    %.o: %.cpp
        ${CC} ${CFLAGS} ${PRODFLAGS} -c -o $@ $^
    
    distances.h: 
        ./gen_distances.pl
    
    clean:
        rm -f main.o perm.o operations.o main maindbg distances.h bsp7 bsp4
    


  • danke perfectoption hab erst jetzt deinen beitrag gelesen.


Anmelden zum Antworten