############################################################################### SHELL := bash .ONESHELL: ############################################################################### ATT = $(EXE:=.att) C = 10 CPU != nproc SRC = $(wildcard *.cc) EXE = $(basename $(SRC)) MAX = 25 MIN = 2 N != sed -n 's/^.* N = \([[:digit:]]*\);.*$$/\1/p' le.cc P1 = 13 P2 = 7 REP = 25 STA = $(EXE:=.sta) T = 12ms TXT = $(EXE:=.txt) LOG = $(EXE:=.log) ############################################################################### CXXFLAGS = -g -O3 -std=c++20 -Wall -Wextra ############################################################################### all: @if make -qs $(TXT); then make -s sort else make -s stat fi att: $(ATT) clave: @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 " just : log(lmedia / emedia) máxima justicia = 0" echo " msg : ln + en" echo " cpu : tiempo de cpu (en milisegundos)" echo " ratio : msg / tiempo" clean: -rm -fv $(ATT) $(EXE) $(TXT) $(LOG) $(STA) core* *~ -find -mindepth 2 -maxdepth 2 -name makefile -execdir make $@ \; default: n$(CPU) $(T) all exe: $(EXE) max: n$(MAX) $(T) all min: n$(MIN) $(T) all sort: clave @declare -a N=('13' '14' '15' '16') declare -a F=('just' 'msg' 'cpu' 'ratio') declare -a R=('' 'r' '' 'r') for (( i=0; i<$${#N[@]}; ++i )); do printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' make -s $(firstword $(TXT)) head -n 1 $(firstword $(TXT)) | sed "s/ \($${F[$$i]}\)/\[\1\]/" printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' make stat | grep -E -w "$$(echo $(EXE) | tr ' ' '|')" | sort -k$${N[$$i]},$${N[$$i]}n$${R[$$i]} -k16,16nr -k13,13n -s done printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' stat: clave @printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' for i in $(TXT); do make -s $$i if [[ "$$i" == "$(firstword $(TXT))" ]]; then head -n1 $$i printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' fi tail -n1 $$i done printf "%$$(($(P1) + $(P2) * 15))s\n" | tr ' ' '-' ############################################################################### %.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 -- ./miecho.sh ./$< > $*.log %.txt: %.log %.sta @LANG=C declare -A l; for (( i = 0; i < $(N) / 2; ++i )); do l["$$i"]="0" done while read v k; do l["$$k"]=$$(bc -lq <<< "$$v / ($(C) * $(REP))") done < <(sed 's/\(.\)/\1\n/g' $*.log | grep "[[:digit:]]" | sort | uniq -c) if (( $${#l[@]} < $(N) / 2 )); then echo "[$*.log]: $${#l[@]} < $$(($(N) / 2))" exit 1 fi ln=0 lmin=0$(C) lmedia=0 ldesv=0 lmax=0 if [ "$${#l[@]}" -gt "0" ]; then lv="[$$(echo $${l[@]} | tr ' ' ',')]" ln=$$(python3 -c "print(sum($$lv))") lmin=$$(python3 -c "print(min($$lv))") lmedia=$$(python3 -c "import statistics; print(statistics.mean($$lv))") if [ "$${#l[@]}" -gt "1" ]; then ldesv=$$(python3 -c "import statistics; print(statistics.stdev($$lv))") fi lmax=$$(python3 -c "print(max($$lv))") fi declare -A e; for (( i = 0; i < $(N) / 2; ++i )); do e["$$i"]="0" done while read v k; do e["$$k"]=$$(bc -lq <<< "$$v / ($(C) * $(REP))") done < <(sed 's/\(.\)/\1\n/g' $*.log | grep "[[:lower:]]" | sort | uniq -c) if (( $${#e[@]} < $(N) / 2 )); then echo "[$*.log]: $${#e[@]} < $$(($(N) / 2))" exit 1 fi en=0 emin=0 emedia=0 edesv=0 emax=0 if [ "$${#e[@]}" -gt "0" ]; then ev="[$$(echo $${e[@]} | tr ' ' ',')]" en=$$(python3 -c "print(sum($$ev))") emin=$$(python3 -c "print(min($$ev))") emedia=$$(python3 -c "import statistics; print(statistics.mean($$ev))") if [ "$${#e[@]}" -gt "1" ]; then edesv=$$(python3 -c "import statistics; print(statistics.stdev($$ev))") fi emax=$$(python3 -c "print(max($$ev))") fi msg=$$(python3 -c "print($$ln + $$en)") cc=$$(grep [0-9] $*.log | grep [a-z] | wc -l) # cc lector/escritor for i in {a..z}; do # cc escritor/escritor for j in $$(eval echo {$$i..z}); do if [[ "$$i" < "$$j" ]]; then if [ "$$(grep $$i$$j $*.log | wc -l)" != "0" ]; then (( ++cc )) fi fi done done (( cc = cc / ($(C) * $(REP)) )) just=$$(bc -lq <<< "l(($$lmedia + 10^-10) / ($$emedia + 10^-10))/l(10)") cpu=$$(grep -o ".* msec task-clock" $*.sta | grep -o "[[:digit:].]*") ratio=$$(bc -lq <<< "$$msg / $$cpu") printf '%$(P1)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s\n' programa cc ln lmin lmedia ldesv lmax en emin emedia edesv emax just msg cpu ratio > $@ printf '%$(P1)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s%$(P2)s\n' $* $$cc $$(printf '%.0f' $$ln) $$(printf '%.0f' $$lmin) $$(printf '%.0f' $$lmedia) $$(printf '%.0f' $$ldesv) $$(printf '%.0f' $$lmax) $$(printf '%.0f' $$en) $$(printf '%.0f' $$emin) $$(printf '%.0f' $$emedia) $$(printf '%.0f' $$edesv) $$(printf '%.0f' $$emax) $$(printf '%.2f' $$just) $$(printf '%.0f' $$msg) $$(printf '%.1f' $$cpu) $$(printf '%.1f' $$ratio) >> $@ n%: $(SRC) @n=$@; n=$$(( $${n:1} / 2 * 2 )) if (( n > $(MAX) )); then n='$(MAX)'; fi sed --follow-symlinks -i "s/const size_t N = .*;/const size_t N = $$n;/" $^ %ms: $(SRC) @sed --follow-symlinks -i "s/^ std::this_thread::sleep_for(.*);/ std::this_thread::sleep_for($@);/" $^ ############################################################################### .PHONY: all clave clean default exe max min sort stat .PRECIOUS: $(STA) $(TXT) $(LOG) ###############################################################################