SHELL := /usr/bin/bash .ONESHELL: ATT = $(EXE:=.att) CAL = $(EXE:=.cal) CCG = $(EXE:=.ccg) BST = $(basename $(shell grep -l 'boost::' $(SRC))) DAT = $(EXE:=.dat) DEP = $(foreach i,$(EXE:=.d),.$(i)) EXE = $(basename $(SRC)) LOG = $(EXE:=.log) REC = $(EXE:=.rec) SRC = $(wildcard *.c *.cc) VER = $(EXE:=.ver) CFLAGS = -g -march=native -MF .$*.d -MMD -MP -O3 -Wall CXXFLAGS = $(CFLAGS) -std=c++23 $(BST): LDLIBS += -lboost_context -lboost_chrono -lboost_fiber -lboost_thread all: exe @if make -qs $(LOG); then make -s sort else make -s programa fi att: $(ATT) clave: @printf "%48s\n" | tr ' ' '-' echo " mensajes: suma de los mensajes emitidos = número de señales" echo " tiempo: task-clock (ms) = tiempo de cpu" echo " ratio: mensajes / tiempo" printf "%48s\n" | tr ' ' '-' printf "%12s%12s%12s%12s\n" programa mensajes tiempo ratio printf "%48s\n" | tr ' ' '-' clean: stop -rm -fv $(ATT) $(CAL) $(CCG) $(DAT) $(DEP) $(EXE) $(LOG) $(REC) perf.data* *~ -find -mindepth 2 -maxdepth 2 -name makefile -execdir make $@ \; dat: $(DAT) exe: $(EXE) log: $(LOG) @for i in $^; do printf "[$$i]%32s\n" | tr ' ' '-' cat $$i done mensajes: clave @make -s ver | sort -k 2,2nr -k 3,3n -k 4,4nr programa: clave ver ratio: clave @make -s ver | sort -k 4,4nr -k 3,3n -k 2,2nr sort: ratio start: @sudo sysctl -w kernel.perf_event_paranoid=-1 &> /dev/null sudo sysctl kernel.yama.ptrace_scope=0 &> /dev/null stat: $(EXE) @for i in $^; do echo $$i perf stat -- ./$$i |& grep -E '(seconds|msec)' done stop: @sudo sysctl -w kernel.perf_event_paranoid=2 &> /dev/null sudo sysctl kernel.yama.ptrace_scope=2 &> /dev/null tiempo: clave @make -s ver | sort -k 3,3n -k 4,4nr -k 2,2nr ver: $(VER) %.att: % objdump -Cd $< > $@ %.cal: % -valgrind --branch-sim=yes --cacheuse=yes --callgrind-out-file=$@ --cache-sim=yes --collect-jumps=yes --demangle=yes --dump-instr=yes --instr-atstart=yes -q --separate-threads=yes --tool=callgrind --trace-jump=yes ./$< %.ccg: % valgrind --cachegrind-out-file=$@ --trace-children=yes --tool=cachegrind ./$< %.cga: %.ccg cg_annotate --auto=yes $< %.dat %.log: % @LANG=C make -s start perf stat -e task-clock -x ';' -- ./$< 2> $*.dat | grep -iv Temporizador 2> /dev/null | sort | uniq -c > $*.log IFS=';' read -r t u _ _ _ _ _ < <(grep -m1 'task-clock' $*.dat) case $$u in msec) echo $$t ;; *) echo $$(bc -l <<< "$$t / 1000000") ;; esac > $*.dat make -s stop %.kcg: %.cal kcachegrind $< %.ltrace: % @printf "%79s\n \t$*\n%79s\n" | tr ' ' '#' make -s start ltrace -cf ./$< 2>&1 >/dev/null | c++filt | cut -c 1-$$(tput cols) make -s stop %.perf: %.rec make -s start perf report -g 'graph,0.5,caller' -i $< make -s stop %.rec: % make -s start -perf record --call-graph dwarf --freq=max -o $@ -- ./$< make -s stop %.strace: % @printf "%79s\n \t$*\n%79s\n" | tr ' ' '#' make -s start strace -cf -qq ./$< 2>&1 >/dev/null | c++filt | cut -c 1-$$(tput cols) make -s stop %.trace: % @printf "%79s\n \t$*\n%79s\n" | tr ' ' '#' make -s start ltrace -cfS ./$< 2>&1 >/dev/null | c++filt | cut -c 1-$$(tput cols) make -s stop %.ver: %.dat %.log @LANG=C n=0; while read i j; do (( n += i )); done < $*.log t=$$(cat $*.dat) printf "%12s%12s%12.2f%12.2f\n" $* $$n $$t $$(bc -l <<< "$$n / $$t") -include $(DEP) .PHONY: all att clean exe log mensajes ratio sort stat programa ver .PRECIOUS: $(CAL) $(CCG) $(DAT) $(LOG) $(REC)