SHELL := bash .ONESHELL: ATT = $(EXE:=.att) CAL = $(EXE:=.cal) REC = $(EXE:=.rec) EXE = $(basename $(SRC)) FOL = $(EXE:=.fol) LOG = $(EXE:=.log) SRC = $(wildcard *.cc) TXT = $(EXE:=.txt) SVG = $(EXE:=.svg) TME = $(EXE:=.tme) CXXFLAGS = -fanalyzer -flto -g -march=native -O3 -std=c++20 -Wall all: @if make -qs $(TXT); then make -s sort else make -s stat fi att: $(ATT) clave: @printf '%118s\n' | tr ' ' '-' echo "clave:" printf '%118s\n' | tr ' ' '-' echo ' bien : número de mensajes correctos' echo ' mal : número de mensajes incorrectos' echo ' total : bien + mal' echo ' hebras: número de hebras que han impreso al menos un mensaje' echo ' min : minimo número de mensajes por hebra' echo ' media : mensajes impresos en media por hebra' echo ' desv : desviación típica de mensajes por hebra' echo ' max : maximo número de mensajes por hebra' echo ' real : tiempo transcurrido en segundos' echo ' user : tiempo de usuario en segundos' echo ' sys : tiempo de sistema en segundos' echo ' cpu : user + sys' echo ' ratio : bien / cpu --> número de mensajes correctos por segundo' clean: -rm -fv $(ATT) $(CAL) $(EXE) $(FOL) $(LOG) $(REC) $(TXT) $(SVG) $(TME) core.* *~ -find -mindepth 2 -iname 'makefile' -execdir make $@ \; exe: $(EXE) sort: clave @declare -a N=(4 5 6 7 8 9 10 11 12 13 14) declare -a F=('total' 'hebras' 'min' 'media' 'desv' 'max' 'real' 'user' 'sys' 'cpu' 'ratio') declare -a R=('r' 'r' 'r' 'r' '' 'r' '' '' '' '' 'r') make -s $(firstword $(TXT)) > /dev/null for (( i=0; i<$${#N[@]}; ++i )); do printf '%118s\n' | tr ' ' '-' head -n 1 $(firstword $(TXT)) | sed "s/ $${F[$$i]}/\[$${F[$$i]}\]/" printf '%118s\n' | tr ' ' '-' make stat | grep -v ':' | grep -E -w "$$(echo $(EXE) | tr ' ' '|')" | sort -k$${N[$$i]},$${N[$$i]}$${R[$$i]} -k14,14nr -k13,13n -k5,5nr -s done printf '%118s\n' | tr ' ' '-' stat: clave @printf '%118s\n' | tr ' ' '-' for i in $(TXT); do make -s $$i &> /dev/null if [ "$$i" == "$(firstword $(TXT))" ]; then head -n 1 $$i printf '%118s\n' | tr ' ' '-' fi tail -n 1 $$i done printf '%118s\n' | tr ' ' '-' %.att: % objdump -C -d -S $< > $@ %.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 ./$< %.rec: % -perf record --call-graph=dwarf -o $@ -- ./$< %.fg: %.svg eog $< & %.fol: %.rec -perf script -i $< | stackcollapse-perf.pl | grep -v cpu_idle > $@ %.hel: % valgrind -s --tool=helgrind ./$< %.kcg: %.cal kcachegrind $< %.log %.tme: % @if hash cpupower; then governor=$$(cpupower frequency-info | sed -n 's/^.*"\(.*\)".*$$/\1/p') echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor sleep 0.001 fi LANG=C TIMEFORMAT='%3R %3U %3S' bash -c "time ./$*" 1> $*.log 2> $*.tme || true if hash cpupower; then echo $$governor | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor fi %.ltrace: % @printf "%79s\n \t$*\n%79s\n" | tr ' ' '#' ltrace -cf ./$< |& c++filt | cut -c 1-$$(tput cols) %.perf: %.rec -perf report -i $< %.strace: % @printf "%79s\n \t$*\n%79s\n" | tr ' ' '#' strace -cf -qq ./$< |& c++filt | cut -c 1-$$(tput cols) %.txt: %.log %.tme @LC_ALL=C if [ "$$(uname -m)" == "x86_64" ]; then lid=15 else lid=10 fi bien=$$(grep -c -E "^\[[[:digit:]]{$$lid}\]: 0123456789$$" $*.log) total=$$(cat $*.log | wc -l) (( mal = total - bien )) hebras=$$(grep -E "^\[[[:digit:]]{$$lid}\]: 0123456789$$" $*.log | sort | uniq -c | wc -l) real=$$(cat $*.tme | cut -d ' ' -f 1) usuario=$$(cat $*.tme | cut -d ' ' -f 2) sistema=$$(cat $*.tme | cut -d ' ' -f 3) cpu=$$(printf "%.3f" $$(bc -lq <<< "$$usuario + $$sistema")) ratio=$$(printf "%.0f" $$(bc -lq <<< "$$bien / $$cpu")) n=$$(sed -n 's/const size_t N = \(.*\);/\1/p' $*.cc) n=$${n:=1} declare -a t=($$(grep -E "^\[[[:digit:]]{$$lid}\]: 0123456789$$" $*.log | sort | uniq -c | tr -d ' ' | cut -d'[' -f1)) for ((i=$${#t[@]}; i $@ printf "%14s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n" $* $$bien $$mal $$total $$hebras $$min $$mean $$stdev $$max $$real $$usuario $$sistema $$cpu $$ratio >> $@ %.trace: % @printf "%79s\n \t$*\n%79s\n" | tr ' ' '#' ltrace -cfS ./$< |& c++filt | cut -c 1-$$(tput cols) %.svg: %.fol flamegraph.pl $< > $@ d%: $(SRC) -@d=$@ for i in $^; do sed --follow-symlinks -i "s/auto delay = .*;/auto delay = $${d:1};/" $$i done find -maxdepth 2 -mindepth 2 -name makefile -execdir make $@ \; n%: $(SRC) -@n=$@ for i in $^; do sed --follow-symlinks -i "s/const size_t N = [^;]*;/const size_t N = $${n:1};/" $$i done find -maxdepth 2 -mindepth 2 -name makefile -execdir make $@ \; %ms: $(SRC) -@t=$@ for i in $^; do sed --follow-symlinks -i "s/^ std::this_thread::sleep_for(.*);/ std::this_thread::sleep_for($@);/" $$i done find -maxdepth 2 -mindepth 2 -name makefile -execdir make $@ \; .PHONY: all att clave clean exe sort stat .PRECIOUS: $(CAL) $(EXE) $(FOL) $(LOG) $(REC) $(TME) $(TXT) .NOEXPORT: