48 lines
1.4 KiB
C
48 lines
1.4 KiB
C
|
|
#ifndef RANDOMINUS_H
|
||
|
|
#define RANDOMINUS_H
|
||
|
|
/* To randomize an array - hopefully as fast as possible */
|
||
|
|
|
||
|
|
#include "fastrand/fastrand.h"
|
||
|
|
|
||
|
|
/** swap */
|
||
|
|
static void inline rd_swap(uint32_t *a, uint32_t *b) {
|
||
|
|
uint32_t tmp = *a;
|
||
|
|
*a = *b;
|
||
|
|
*b = tmp;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** This is by no means "cryptographically correct" or stuff, but fast */
|
||
|
|
static inline void randominus(uint32_t *a, int n, uint32_t seed) {
|
||
|
|
|
||
|
|
/** Initialized ILP random generator */
|
||
|
|
uint32_t ilp_seeds[8];
|
||
|
|
rand_ilp_state rsi;
|
||
|
|
rand_state rs = init_rand();
|
||
|
|
for(int i = 0; i < 8; ++i) {
|
||
|
|
uint32_t choice = rand_between(&rs, 0, n);
|
||
|
|
ilp_seeds[i] = choice;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Go over the array and randomly swap stuff - hand unrolled with ILP random get! */
|
||
|
|
for(int i = 0; i < (n - 8); i += 8) {
|
||
|
|
uint32_t to0 = fastmodlike(lcg_ilp(&rsi, A), n);
|
||
|
|
uint32_t to1 = fastmodlike(lcg_ilp(&rsi, B), n);
|
||
|
|
uint32_t to2 = fastmodlike(lcg_ilp(&rsi, C), n);
|
||
|
|
uint32_t to3 = fastmodlike(lcg_ilp(&rsi, D), n);
|
||
|
|
uint32_t to4 = fastmodlike(lcg_ilp(&rsi, E), n);
|
||
|
|
uint32_t to5 = fastmodlike(lcg_ilp(&rsi, F), n);
|
||
|
|
uint32_t to6 = fastmodlike(lcg_ilp(&rsi, G), n);
|
||
|
|
uint32_t to7 = fastmodlike(lcg_ilp(&rsi, H), n);
|
||
|
|
rd_swap(&a[i], &a[to0]);
|
||
|
|
rd_swap(&a[i + 1], &a[to1]);
|
||
|
|
rd_swap(&a[i + 2], &a[to2]);
|
||
|
|
rd_swap(&a[i + 3], &a[to3]);
|
||
|
|
rd_swap(&a[i + 4], &a[to4]);
|
||
|
|
rd_swap(&a[i + 5], &a[to5]);
|
||
|
|
rd_swap(&a[i + 6], &a[to6]);
|
||
|
|
rd_swap(&a[i + 7], &a[to7]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif /* RANDOMINUS_H */
|