diff --git a/Makefile b/Makefile index 88de154..924e096 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # -CFLAGS=-std=gnu99 -g -O3 -fomit-frame-pointer -fno-unroll-loops -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wmissing-declarations -Wnested-externs -Wpointer-arith -W -Wno-unused-parameter -Werror -pthread -Wno-tautological-compare +CPPFLAGS=-g -O3 -fomit-frame-pointer -fno-unroll-loops -Wall -Wshadow -Wmissing-declarations -Wpointer-arith -W -Wno-unused-parameter -Werror -pthread -Wno-tautological-compare + +CFLAGS=-std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs +CXXFLAGS=-std=gnu++11 + LDFLAGS=-g -O3 -static -pthread LDLIBS=-lrt -lm @@ -20,9 +24,9 @@ ARCH ?= $(shell uname -m) ifeq ($(ARCH),aarch64) CAP ?= $(shell cat /proc/cpuinfo | grep -E 'atomics|sve' | head -1) ifneq (,$(findstring sve,$(CAP))) - CFLAGS+=-march=armv8.2-a+sve + CPPFLAGS+=-march=armv8.2-a+sve else ifneq (,$(findstring atomics,$(CAP))) - CFLAGS+=-march=armv8.1-a+lse + CPPFLAGS+=-march=armv8.1-a+lse endif endif @@ -36,9 +40,9 @@ clean: .c.s: $(CC) $(CFLAGS) -S -c $< -multichase: multichase.o permutation.o arena.o util.o +multichase: multichase.o permutation.o random.o arena.o util.o -multiload: multiload.o permutation.o arena.o util.o +multiload: multiload.o permutation.o random.o arena.o util.o fairness: LDLIBS += -lm @@ -51,10 +55,11 @@ depend: # DO NOT DELETE -arena.o: arena.h -multichase.o: cpu_util.h timer.h expand.h permutation.h arena.h util.h -multiload.o: cpu_util.h timer.h expand.h permutation.h arena.h util.h -permutation.o: permutation.h +arena.o: arena.h random.h +multichase.o: cpu_util.h timer.h expand.h permutation.h random.h arena.h util.h +multiload.o: cpu_util.h timer.h expand.h permutation.h random.h arena.h util.h +permutation.o: permutation.h random.h +random.o: random.h util.o: util.h fairness.o: cpu_util.h expand.h timer.h pingpong.o: cpu_util.h timer.h diff --git a/arena.c b/arena.c index f1933ed..d73866d 100644 --- a/arena.c +++ b/arena.c @@ -23,7 +23,7 @@ #include #include -#include "permutation.h" +#include "random.h" extern int verbosity; extern int is_weighted_mbind; diff --git a/multichase.c b/multichase.c index f175c29..2b0bfea 100644 --- a/multichase.c +++ b/multichase.c @@ -29,6 +29,7 @@ #include "cpu_util.h" #include "expand.h" #include "permutation.h" +#include "random.h" #include "timer.h" #include "util.h" diff --git a/multiload.c b/multiload.c index 6653da5..912dbf2 100644 --- a/multiload.c +++ b/multiload.c @@ -29,6 +29,7 @@ #include "cpu_util.h" #include "expand.h" #include "permutation.h" +#include "random.h" #include "timer.h" #include "util.h" diff --git a/permutation.c b/permutation.c index a26648a..200686a 100644 --- a/permutation.c +++ b/permutation.c @@ -20,6 +20,8 @@ #include #include +#include "random.h" + // some asserts are more expensive than we want in general use, but there are a // few i want active even in general use. #if 1 diff --git a/permutation.h b/permutation.h index c093d3c..19ba14f 100644 --- a/permutation.h +++ b/permutation.h @@ -73,47 +73,4 @@ void *generate_chase(const struct generate_chase_common_args *args, void *generate_chase_long(const struct generate_chase_common_args *args, size_t mixer_idx, size_t total_par); -//============================================================================ -// Modern multicore CPUs have increasingly large caches, so the LCRNG code -// that was previously used is not sufficiently random anymore. -// Now using glibc's reentrant random number generator "random_r" -// still reproducible on the same platform, although not across systems/libs. - -// RNG_BUF_SIZE sets the size of rng_buf below, which is used by initstate_r -// to decide how sophisticated a random number generator it should use: the -// larger the state array, the better the random numbers will be. -// 32 bytes was deemed to generate sufficient entropy. -#define RNG_BUF_SIZE 32 -extern __thread char *rng_buf; -extern __thread struct random_data *rand_state; - -static inline void rng_init(unsigned thread_num) { - rng_buf = (char *)calloc(1, RNG_BUF_SIZE); - rand_state = (struct random_data *)calloc(1, sizeof(struct random_data)); - assert(rand_state); - if (initstate_r(thread_num, rng_buf, RNG_BUF_SIZE, rand_state) != 0) { - perror("initstate_r"); - exit(1); - } -} - -static inline perm_t rng_int(perm_t limit) { - int r1, r2, r3, r4; - uint64_t r; - - if (random_r(rand_state, &r1) || random_r(rand_state, &r2) - || random_r(rand_state, &r3) || random_r(rand_state, &r4)) { - perror("random_r"); - exit(1); - } - // Assume that RAND_MAX is at least 16-bit long - _Static_assert (RAND_MAX >= (1ul << 16), "RAND_MAX is too small"); - r = (((uint64_t)r1 << 0) & 0x000000000000FFFFull) | - (((uint64_t)r2 << 16) & 0x00000000FFFF0000ull) | - (((uint64_t)r3 << 32) & 0x0000FFFF00000000ull) | - (((uint64_t)r4 << 48) & 0xFFFF000000000000ull); - - return r % (limit + 1); -} - #endif diff --git a/random.cc b/random.cc new file mode 100644 index 0000000..4eeb65e --- /dev/null +++ b/random.cc @@ -0,0 +1,27 @@ +/* Copyright 2022 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "random.h" + +#include + +static thread_local std::mt19937 engine; + +void rng_init(unsigned thread_num) { + engine.seed(thread_num); +} + +uint32_t rng_int(uint32_t limit) { + return engine() % (limit + 1); +} diff --git a/random.h b/random.h new file mode 100644 index 0000000..7aa3986 --- /dev/null +++ b/random.h @@ -0,0 +1,31 @@ +/* Copyright 2022 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RANDOM_H_INCLUDED +#define RANDOM_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void rng_init(unsigned thread_num); +uint32_t rng_int(uint32_t limit); + +#ifdef __cplusplus +} +#endif + +#endif