SHELL := bash CFLAGS := -O3 -g FINGERPRINT := $(shell ./shishua -b 256 2>/dev/null | ./bin/fingerprint.sh) TARGETS := scalar sse2 ssse3 avx2 neon SHISHUAS := shishua shishua-half \ $(addprefix shishua-,$(TARGETS)) \ $(addprefix shishua-half-,$(TARGETS)) PRNGS := shishua shishua-half chacha8 xoshiro256plusx8 xoshiro256plus romu wyrand lehmer128 rc4 # Should match header names (aside from -scalar and -ssse3) IMPLS := $(SHISHUAS) chacha8 chacha8-avx2 chacha8-neon xoshiro256plusx8 xoshiro256plus romu wyrand lehmer128 rc4 TESTS := $(addprefix test/vectors-,$(TARGETS)) # We need second expansions. .SECONDEXPANSION: ## ## Target rules. ## # Replace pseudo target names with the real names. # The HEADER preproc variable is used in prng.c. fix_target = $(subst -scalar,,$(subst -ssse3,-sse2,$(1))) $(IMPLS): HEADER = $(call fix_target,$@).h # HEADERS ensures modifications on -neon.h etc. cause recompiles. $(PRNGS): HEADERS = $(call fix_target,$@)*.h $(TESTS): SUFFIX = $(patsubst test/vectors%,%.h,$(call fix_target,$@)) # Force SSE2, disable SSE3 %-sse2: CFLAGS += -msse2 -mno-sse3 -mno-ssse3 %-ssse3: CFLAGS += -mssse3 # -mtune=haswell disables GCC load/store splitting %-avx2: CFLAGS += -mavx2 -mtune=haswell # force scalar target %-scalar: CFLAGS += -DSHISHUA_TARGET=SHISHUA_TARGET_SCALAR ifeq ($(shell $(CC) -v 2>&1 | tail -1 | grep -o gcc),gcc) xoshiro256plusx8: CFLAGS += -fdisable-tree-cunrolli CFLAGS += -march=native else CFLAGS += -mcpu=native endif ## ## Recipes. ## default: shishua shishua-half # e.g. make neon -> make shishua-neon shishua-half-neon $(TARGETS): %: shishua-% shishua-half-% $(IMPLS): $$(HEADER) $$(HEADERS) prng.c $(CC) $(CFLAGS) -DHEADER='"$(HEADER)"' prng.c -o $@ intertwine: intertwine.c $(CC) $(CFLAGS) -o $@ $< ## ## Quality testing. ## /usr/local/bin/RNG_test: mkdir PractRand curl -Ls 'https://downloads.sourceforge.net/project/pracrand/PractRand-pre0.95.zip' >PractRand/PractRand.zip cd PractRand; \ unzip PractRand.zip; \ g++ -c src/*.cpp src/RNGs/*.cpp src/RNGs/other/*.cpp -O3 -Iinclude -pthread; \ ar rcs libPractRand.a *.o; \ g++ -o RNG_test tools/RNG_test.cpp libPractRand.a -O3 -Iinclude -pthread; \ g++ -o RNG_benchmark tools/RNG_benchmark.cpp libPractRand.a -O3 -Iinclude -pthread; \ g++ -o RNG_output tools/RNG_output.cpp libPractRand.a -O3 -Iinclude -pthread sudo mv PractRand/RNG_{test,benchmark,output} /usr/local/bin rm -rf PractRand /usr/local/bin/testu01: testu01.c curl -sO 'http://simul.iro.umontreal.ca/testu01/TestU01.zip' unzip TestU01.zip mv TestU01-*/ testu01 cd testu01; \ ./configure --prefix=/usr/local; \ make; sudo make install rm -rf TestU01* testu01 gcc -std=c99 -Wall -O3 -o testu01 testu01.c -Iinclude -Llib -ltestu01 -lprobdist -lmylib -lm sudo mv testu01 /usr/local/bin/ test: test/perf-$(FINGERPRINT) test/vectors test/PractRand-$(FINGERPRINT) test/BigCrush-$(FINGERPRINT) test/vectors: @mkdir -p test make test/vectors-scalar make test/vectors-sse2 make test/vectors-ssse3 make test/vectors-avx2 #make test/vectors-neon $(TESTS): test-vectors.c test-vectors.h shishua$$(SUFFIX) shishua-half$$(SUFFIX) $(CC) $(CFLAGS) -DHEADER='"shishua$(SUFFIX)"' -DHEADER_HALF='"shishua-half$(SUFFIX)"' $< -o $@ ./$@ >> test/vectors test/PractRand-$(FINGERPRINT): /usr/local/bin/RNG_test shishua @mkdir -p test @echo "Date $$(date)" | tee test/PractRand-$(FINGERPRINT) @echo "PRNG fingerprint: $(FINGERPRINT)" | tee -a test/PractRand-$(FINGERPRINT) ./shishua | RNG_test stdin64 | tee -a test/PractRand-$(FINGERPRINT) test/BigCrush-$(FINGERPRINT): /usr/local/bin/testu01 shishua @mkdir -p test @echo "Date $$(date)" | tee test/BigCrush-$(FINGERPRINT) @echo "PRNG fingerprint: $(FINGERPRINT)" | tee -a test/BigCrush-$(FINGERPRINT) ./shishua | testu01 --big | tee -a test/BigCrush-$(FINGERPRINT) test/benchmark-seed: $(PRNGS) intertwine @mkdir -p test @echo "Date $$(date)" | tee $@ for prng in $(PRNGS); do \ echo "$$prng fingerprint: $$(./$$prng | ./bin/fingerprint.sh)" | tee -a $@; \ ./intertwine <(./$$prng -s 1) <(./$$prng -s 2) \ <(./$$prng -s 4) <(./$$prng -s 8) \ <(./$$prng -s 10) <(./$$prng -s 20) \ <(./$$prng -s 40) <(./$$prng -s 80) \ | RNG_test stdin -tlmax 1M -tlmin 1K -te 1 -tf 2 | tee -a $@; \ done ## ## Performance testing. ## # This must be performed with no other processes running. test/perf-$(FINGERPRINT): shishua @mkdir -p test @echo "Date $$(date)" | tee $@ @echo "PRNG fingerprint: $(FINGERPRINT)" | tee -a $@ ./shishua --bytes 4294967296 -q 2>&1 | tee -a $@ test/benchmark-perf: $(PRNGS) @mkdir -p test @echo "Date $$(date)" | tee $@ for prng in $(PRNGS); do \ ./bin/fix-cpu-freq.sh ./$$prng --bytes 10000000000 -q 2>&1 | tee -a $@; \ done @echo | tee -a $@ @lscpu | tee -a $@ # To reach a consistent benchmark, we need a universally-reproducible system. # GCP will do. # Installation instructions from https://cloud.google.com/sdk/docs/downloads-apt-get /usr/bin/gcloud: echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list sudo apt-get install apt-transport-https ca-certificates gnupg curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - sudo apt-get update && sudo apt-get install google-cloud-sdk gcloud init # Installation instructions for Amazon Web Services CLI (for ARM servers with NEON) # available here: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html /usr/local/bin/aws: curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install rm -r awscliv2.zip aws aws configure # Installation instructions for Scaleway CLI (for ARM servers without NEON) # available here: https://github.com/scaleway/scaleway-cli#linux /usr/local/bin/scw: sudo curl -o /usr/local/bin/scw -L "https://github.com/scaleway/scaleway-cli/releases/download/v2.3.0/scw-2.3.0-linux-x86_64" sudo chmod +x /usr/local/bin/scw scw init test/benchmark-perf-intel: /usr/bin/gcloud ./bin/benchmark-intel test/benchmark-perf-amd: /usr/bin/gcloud ./bin/benchmark-amd test/benchmark-perf-arm: /usr/local/bin/aws ./bin/benchmark-arm test/benchmark-perf-arm-without-neon: /usr/local/bin/scw ./bin/benchmark-arm-without-neon clean: $(RM) -rf $(TESTS) $(IMPLS) intertwine .PHONY: test clean