############################################################################### .ONESHELL: ############################################################################### ATT = $(EXE:=.att) CAC = $(EXE:=.cac) CAL = $(EXE:=.cal) DAT = $(EXE:=.dat) DEP = $(addprefix .,$(EXE:=.d)) EXE = $(basename $(SRC)) LOG = $(addsuffix .log,$(filter-out test,$(EXE))) SRC = $(wildcard *.cc) STA = $(addsuffix .sta,$(filter-out test,$(EXE))) TXT = $(addsuffix .txt,$(filter-out test,$(EXE))) ############################################################################### DEBUG = -fno-inline -Og OPT = -O3 CXXFLAGS = -fanalyzer -g -MF .$*.d -MMD -pthread -std=c++20 -Wall $(OPT) LDFLAGS = -L.. LDLIBS = -latomic -ldl -lrpmalloc ifeq ($(findstring stm,$(notdir $(CURDIR))),stm) CXXFLAGS += -fgnu-tm DEBUG += -Os # trick to avoid undefined behavior!!! else DEBUG += -fsanitize={address,alignment,bool,bounds,bounds-strict,builtin,enum,float-cast-overflow,float-divide-by-zero,integer-divide-by-zero,leak,nonnull-attribute,null,object-size,pointer-compare,pointer-overflow,pointer-subtract,return,returns-nonnull-attribute,shift,shift-base,shift-exponent,signed-integer-overflow,undefined,unreachable,vla-bound,vptr} endif # ifeq ($(findstring tag,$(notdir $(CURDIR))),tag) # DEBUG = -fanalyzer -fno-inline -g -mno-{avx,sse} -Og # trick to avoid heap use after free!!! # endif ############################################################################### all: ld txt att: $(ATT) check: $(EXE) @for i in $^; do if nm -C ./$$i | grep -q rpmalloc; then echo "rpmalloc lib detected in $${PWD##*/}/$$i" else echo "rpmalloc lib NOT DETECTED in $${PWD##*/}/$$i!!!" fi done clean: -rm -fv $(ATT) $(EXE) $(CAC) $(CAL) $(DAT) $(DEP) $(LOG) $(STA) $(TXT) callgrind.out.* core.* perf.* *.dat.old *~ dep: $(DEP) exe: $(EXE) ld: @LD_LIBRARY_PATH=$$LD_LIBRARY_PATH export LD_LIBRARY_PATH log: $(LOG) sta: $(STA) txt: $(TXT) ############################################################################### -include $(DEP) %.att: % objdump -Cd $< > $@ %.cac: % valgrind --cachegrind-out-file=$@ --tool=cachegrind ./$< %.cal: % valgrind --tool=callgrind --branch-sim=yes --cache-sim=yes --callgrind-out-file=$@ --collect-bus=yes --collect-jumps=yes --dump-instr=yes --dump-line=yes -- ./$< %.cga: %.cac cg_annotate --auto=yes $< %.dat: % perf record --call-graph dwarf --freq=max -o $@ -- ./$< %.hel: % valgrind --tool=helgrind -- ./$< %.kcg: %.cal kcachegrind $< & %.leak: % # valgrind --leak-check=full -s --show-leak-kinds=all ./$< valgrind --leak-check=summary --show-leak-kinds=all ./$< %.log %.sta: % @LANG=C perf stat -r 33 > $*.log 2> $*.sta -- ./$< %.ltrace: % ltrace -cfS ./$< |& c++filt %.perf: %.dat perf report -g 'graph,0.5,caller' -i $< %.txt: %.log %.sta @v="[$$(cat $*.log | tr '\n' ',')]" sum=$$(python3 -c "import statistics; print('{0:.0f}'.format(sum($$v)))") median=$$(python3 -c "import statistics; print('{0:.0f}'.format(statistics.median($$v)))") mean=$$(python3 -c "import statistics; print('{0:.0f}'.format(statistics.mean($$v)))") stdev=$$(python3 -c "import statistics; print('{0:.0f}'.format(statistics.stdev($$v)))") cpu=$$(grep -o ".* msec task-clock" $*.sta | grep -o "[[:digit:].]*") # ratio=$$(python3 -c "print('{0:.2f}'.format($$sum / $$cpu))") ratio=$$(python3 -c "print('{0:.2f}'.format($$median / $$cpu))") hc=$$(grep 'N = 1;' stack.cc > /dev/null && echo '.' || echo ':') printf "%18s%10s%10s%10s%10s%10s\n" program median mean stdev cpu ratio | tee $@ printf "%18s%10s%10s%10s%10s%10s\n" "$$(basename $$(pwd))$$hc" $$median $$mean $$stdev $$cpu $$ratio | tee -a $@ ############################################################################### .PHONY: all att check clean dep exe log sta txt .PRECIOUS: $(CAC) $(CAL) $(DAT) $(LOG) $(STA) $(TXT) ###############################################################################