############################################################################### SHELL := /usr/bin/bash .ONESHELL: ############################################################################### ATT = $(EXE:=.att) C = 10 # caracteres por mensaje SRC = $(sort $(wildcard *.c *.cc)) EXE = $(basename $(SRC)) N = 8 # número de hebras P1 = 13 # relleno nombre programa P2 = 7 # relleno columnas REP = 11 # repeticiones del experimento STA = $(EXE:=.sta) TXT = $(EXE:=.txt) LOG = $(EXE:=.log) ############################################################################### CXXFLAGS = -flto -march=native -O3 -pthread -Wall # -std=c++17 ############################################################################### all: stat att: $(ATT) clave: | exe @printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' echo "clave:" printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' echo " cc : condiciones de carrera = escrituras incorrectas" echo " ln : número de total de lecturas (siempre correctas)" echo " lmin : mínimo número de lecturas" echo " lmedia : número medio de lecturas" echo " ldesv : desviación típica del número de lecturas" echo " lmax : máximo número de lecturas" echo " en : número de total de escrituras (no siempre correctas)" echo " emin : mínimo número de escrituras" echo " emedia : número medio de escrituras" echo " edesv : desviación típica del número de escrituras" echo " emax : máximo número de escrituras" echo " msg : ln + en" echo " ratio1 : log(ln / en) máxima justicia = 0" echo " cpu : tiempo de cpu (en milisegundos)" echo " ratio2 : msg / tiempo" clean: -rm -fv $(ATT) $(EXE) $(TXT) $(LOG) $(STA) core* *~ -find -mindepth 2 -maxdepth 2 -name makefile -execdir make $@ \; exe: $(EXE) stat: | clave @printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' make -s $(firstword $(TXT)) head -n 1 $(firstword $(TXT)) printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' for i in $(TXT); do make -s $$i tail -n 1 -q $$i done printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' sort: $(TXT) | clave @declare -a F=('programa' 'cc' 'ln' 'lmin' 'lmedia' 'ldesv' 'lmax' 'en' 'emin' 'emedia' 'edesv' 'emax' 'msg' 'ratio1' 'cpu' 'ratio2') declare -a R=('-s' '-s' '-r' '-r' '-r' '-s' '-r' '-r' '-r' '-r' '-s' '-r' '-r' '-s' '-s' '-r') printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' for (( i=0; i<$${#F[@]}; ++i )); do head -n 1 -q $(firstword $(TXT)) | sed "s/ $${F[$$i]}/\[$${F[$$i]}\]/" printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' tail -n 1 -q $^ | sort -n -k$$(($${#F[@]} + 1)),$$(($${#F[@]} + 1)) -k$$((i + 1)),$$((i + 1)) $${R[$$i]} printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' done ############################################################################### %.att: % objdump -Cd $< > $@ %.leak: % valgrind --leak-check=full -s --show-leak-kinds=all ./$< %.log %.sta: % # sudo sysctl kernel.perf_event_paranoid=-1 # por si perf falla... @LANG=C perf stat -r $(REP) 2> $*.sta -- ./$< > $*.log %.txt: %.log %.sta @LANG=C lpad() { printf "%$$(( $$2 - $${#1} ))s$${1}"; } pprint() { lpad "$$1" $(P1); shift; for p in "$$@"; do lpad "$$p" $(P2); done; echo; } declare -a l=($$(sed 's/\(.\)/\1\n/g' $*.log | grep "[[:digit:]]" | sort | uniq -c | sed 's/\(.*\) \(.*\)/\1/g')) if (( $${#l[@]} < $(N) )); then echo "$${#l[@]} < $(N)"; exit 1; fi for ((i=0; i<$${#l[@]}; ++i)); do l[$$i]=$$(bc -lq <<< "$${l[$$i]} / ($(C) * $(REP))") done lv="[$$(echo $${l[@]} | tr ' ' ',')]" ln=$$(printf "%.0f" $$(python3 -c "print(sum($$lv))")) lmin=$$(printf "%.1f" $$(python3 -c "print(min($$lv))")) lmedia=$$(printf "%.1f" $$(python3 -c "import statistics; print(statistics.mean($$lv))")) ldesv=$$(printf "%.1f" $$(python3 -c "import statistics; print(statistics.stdev($$lv))")) lmax=$$(printf "%.0f" $$(python3 -c "print(max($$lv))")) declare -a e=($$(sed 's/\(.\)/\1\n/g' $*.log | grep "[[:lower:]]" | sort | uniq -c | sed 's/\(.*\) \(.*\)/\1/g')) for ((i=0; i<$${#e[@]}; ++i)); do e[$$i]=$$(printf "%0.1f" $$(bc -lq <<< "$${e[$$i]} / ($(C) * $(REP))")) done ev="[$$(echo $${e[@]} | tr ' ' ',')]" en=$$(printf "%.0f" $$(python3 -c "print(sum($$ev))")) emin=$$(printf "%.1f" $$(python3 -c "print(min($$ev))")) emedia=$$(printf "%.1f" $$(python3 -c "import statistics; print(statistics.mean($$ev))")) edesv=$$(printf "%.1f" $$(python3 -c "import statistics; print(statistics.stdev($$ev))")) emax=$$(printf "%.0f" $$(python3 -c "print(max($$ev))")) msg=$$(printf "%.0f" $$(python3 -c "print($$ln + $$en)")) cc=$$(grep [0-9] $*.log | grep [a-h] | wc -l) # cc lector/escritor for i in {a..h}; do # cc escritor/escritor for j in $$(eval echo {$$i..h}); do if [[ "$$i" < "$$j" ]]; then if [ "$$(grep $$i $*.log | grep $$j | wc -l)" != "0" ]; then (( ++cc )) fi fi done done ratio1=$$(printf "%.2f" $$(bc -lq <<< "l($$ln / $$en)/l(10)")) cpu="$$(printf "%.1f" $$(grep -o ".* msec task-clock" $*.sta | grep -o "[[:digit:].]*"))" ratio2=$$(printf "%.1f" $$(bc -lq <<< "$$msg / $$cpu")) pprint programa cc ln lmin lmedia ldesv lmax en emin emedia edesv emax msg ratio1 cpu ratio2 > $@ pprint $* $$cc $$ln $$lmin $$lmedia $$ldesv $$lmax $$en $$emin $$emedia $$edesv $$emax $$msg $$ratio1 $$cpu $$ratio2 >> $@ sf%: $(SRC) -@n="$@" for i in $^; do \ sed "s/sleep_for(.*ms);/sleep_for($${n:2}ms);/" -i $$i done find -maxdepth 2 -mindepth 2 -name makefile -execdir make $@ \; n%: $(SRC) -@n="$@" for i in $^; do \ sed "s/const unsigned N = [^;]*;/const unsigned N = $${n:1};/" -i $$i done find -maxdepth 2 -mindepth 2 -name makefile -execdir make $@ \; ############################################################################### bacon2 ballhausen2 rwlock-t: CXXFLAGS += -std=c++20 ############################################################################### .PHONY: all clave clean exe sort stat .PRECIOUS: $(STA) $(TXT) $(LOG) ###############################################################################