makefile (4849B)
1 SHELL := /bin/bash ## <= required to use time 2 # Interface: 3 # make 4 # make build 5 # make format 6 # make run 7 8 # Compiler 9 CC=gcc 10 # CC=tcc # <= faster compilation 11 12 # Main file 13 SRC=samples.c 14 OUTPUT=out/samples 15 16 SRC_ONE_THREAD=./samples-one-thread.c 17 OUTPUT_ONE_THREAD=out/samples-one-thread 18 19 ## Dependencies 20 # Has no dependencies 21 MATH=-lm 22 23 ## Flags 24 DEBUG= #'-g' 25 STANDARD=-std=c99 26 WARNINGS=-Wall 27 OPTIMIZED=-O3 #-O3 actually gives better performance than -Ofast, at least for this version. Could also add -march=native 28 MORE_OPTIMIZATIONS=-Ofast -funit-at-a-time -march=native -fno-math-errno -ffast-math -std=gnu99 -fno-unroll-loops -flto 29 LOCAL=-march=native 30 OPENMP=-fopenmp 31 32 ## Formatter 33 STYLE_BLUEPRINT=webkit 34 FORMATTER=clang-format -i -style=$(STYLE_BLUEPRINT) 35 36 37 ## make build 38 build: $(SRC) 39 $(CC) $(OPTIMIZED) $(DEBUG) $(SRC) $(LOCAL) $(OPENMP) $(MATH) -o $(OUTPUT) 40 41 build-experimental: 42 # https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html 43 rm -f *.gcda 44 $(CC) -fprofile-generate $(OPTIMIZATIONS) $(LOCAL) samples.c $(OPENMP) $(MATH) -o $(OUTPUT) 45 ./$(OUTPUT) 46 $(CC) -fprofile-use $(OPTIMIZATIONS) $(LOCAL) samples.c $(OPENMP) $(MATH) -o $(OUTPUT) 47 rm *.gcda 48 # Using -Ofast increases speed a bit, but I don't trust it. <https://stackoverflow.com/questions/61232427/gcc-differences-between-o3-vs-ofast-optimizations> 49 50 static: 51 $(CC) $(OPTIMIZED) $(DEBUG) $(SRC) $(LOCAL) $(OPENMP) $(MATH) -o $(OUTPUT) 52 53 format: $(SRC) 54 $(FORMATTER) $(SRC) 55 56 run: $(SRC) $(OUTPUT) 57 OMP_NUM_THREADS=1 ./$(OUTPUT) && echo 58 59 run-16: $(SRC) $(OUTPUT) 60 OMP_NUM_THREADS=16 ./$(OUTPUT) && echo 61 62 multi: 63 OMP_NUM_THREADS=1 ./$(OUTPUT) && echo 64 OMP_NUM_THREADS=2 ./$(OUTPUT) && echo 65 OMP_NUM_THREADS=4 ./$(OUTPUT) && echo 66 OMP_NUM_THREADS=8 ./$(OUTPUT) && echo 67 OMP_NUM_THREADS=16 ./$(OUTPUT) && echo 68 69 ## Timing 70 71 time-linux: 72 @echo "Requires /bin/time, found on GNU/Linux systems" && echo 73 74 @echo "Running 100x and taking avg time: OMP_NUM_THREADS=1 $(OUTPUT)" 75 @t=$$(/usr/bin/time -f "%e" -p bash -c 'for i in {1..100}; do OMP_NUM_THREADS=1 $(OUTPUT); done' 2>&1 >/dev/null | grep real | awk '{print $$2}' ); echo "scale=2; 1000 * $$t / 100" | bc | sed "s|^|Time using 1 thread: |" | sed 's|$$|ms|' && echo 76 77 @echo "Running 100x and taking avg time: OMP_NUM_THREADS=2 $(OUTPUT)" 78 @t=$$(/usr/bin/time -f "%e" -p bash -c 'for i in {1..100}; do OMP_NUM_THREADS=2 $(OUTPUT); done' 2>&1 >/dev/null | grep real | awk '{print $$2}' ); echo "scale=2; 1000 * $$t / 100" | bc | sed "s|^|Time using 2 threads: |" | sed 's|$$|ms|' && echo 79 80 @echo "Running 100x and taking avg time: OMP_NUM_THREADS=4 $(OUTPUT)" 81 @t=$$(/usr/bin/time -f "%e" -p bash -c 'for i in {1..100}; do OMP_NUM_THREADS=4 $(OUTPUT); done' 2>&1 >/dev/null | grep real | awk '{print $$2}' ); echo "scale=2; 1000 * $$t / 100" | bc | sed "s|^|Time for 4 threads: |" | sed 's|$$|ms|' && echo 82 83 @echo "Running 100x and taking avg time: OMP_NUM_THREADS=8 $(OUTPUT)" 84 @t=$$(/usr/bin/time -f "%e" -p bash -c 'for i in {1..100}; do OMP_NUM_THREADS=8 $(OUTPUT); done' 2>&1 >/dev/null | grep real | awk '{print $$2}' ); echo "scale=2; 1000 * $$t / 100" | bc | sed "s|^|Time using 8 threads: |" | sed 's|$$|ms|' && echo 85 86 @echo "Running 100x and taking avg time: OMP_NUM_THREADS=16 $(OUTPUT)" 87 @t=$$(/usr/bin/time -f "%e" -p bash -c 'for i in {1..100}; do OMP_NUM_THREADS=16 $(OUTPUT); done' 2>&1 >/dev/null | grep real | awk '{print $$2}' ); echo "scale=2; 1000 * $$t / 100" | bc | sed "s|^|Time using 16 threads: |" | sed 's|$$|ms|' && echo 88 89 time-linux-fastest: 90 @echo "Running 100x and taking avg time: OMP_NUM_THREADS=16 $(OUTPUT)" 91 @t=$$(/usr/bin/time -f "%e" -p bash -c 'for i in {1..100}; do OMP_NUM_THREADS=16 $(OUTPUT); done' 2>&1 >/dev/null | grep real | awk '{print $$2}' ); echo "scale=2; 1000 * $$t / 100" | bc | sed "s|^|Time using 16 threads: |" | sed 's|$$|ms|' && echo 92 93 time-linux-simple: 94 @echo "Requires /bin/time, found on GNU/Linux systems" && echo 95 OMP_NUM_THREADS=1 /bin/time -f "Time: %es" ./$(OUTPUT) && echo 96 OMP_NUM_THREADS=2 /bin/time -f "Time: %es" ./$(OUTPUT) && echo 97 OMP_NUM_THREADS=4 /bin/time -f "Time: %es" ./$(OUTPUT) && echo 98 OMP_NUM_THREADS=8 /bin/time -f "Time: %es" ./$(OUTPUT) && echo 99 OMP_NUM_THREADS=16 /bin/time -f "Time: %es" ./$(OUTPUT) && echo 100 101 ## Profiling 102 103 profile-linux: 104 echo "Requires perf, which depends on the kernel version, and might be in linux-tools package or similar" 105 echo "Must be run as sudo" 106 $(CC) $(SRC) $(OPENMP) $(MATH) -o $(OUTPUT) 107 # ./$(OUTPUT) 108 # gprof: 109 # gprof $(OUTPUT) gmon.out > analysis.txt 110 # rm gmon.out 111 # vim analysis.txt 112 # rm analysis.txt 113 # perf: 114 OMP_NUM_THREADS=16 sudo perf record $(OUTPUT) 115 sudo perf report 116 rm perf.data 117 118 119 ## Install 120 debian-install-dependencies: 121 sudo apt-get install libomp-dev 122