blob: 6c720c32520f54f5252e84f0c7c10e2877661ab2 [file] [log] [blame]
#pragma once
#include <time.h>
#if defined(__AVR__)
int freeRAM()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start: (int) __brkval);
}
#endif
// A READONLY buffer of RANDOM LENGTH and RANDOM CONTENT
template <typename T>
class random_numerators {
private:
uint32_t *_pData;
uint32_t _length;
uint32_t *allocate(uint32_t size) {
#if defined(__AVR__)
return (uint32_t *)malloc(size);
#elif defined(LIBDIVIDE_WINDOWS)
/* Align memory to 64 byte boundary for AVX512 */
return (uint32_t *)_aligned_malloc(size, 64);
#else
/* Align memory to 64 byte boundary for AVX512 */
void *ptr = NULL;
int failed = posix_memalign(&ptr, 64, size);
if (failed) {
printf("Failed to align memory!\n");
exit(1);
}
return (uint32_t *)ptr;
#endif
}
static void deallocate(uint32_t *pData) {
#if defined(LIBDIVIDE_WINDOWS)
_aligned_free((void *)pData);
#else
free((void *)pData);
#endif
}
struct random_state {
uint32_t hi;
uint32_t lo;
};
static uint32_t my_random(struct random_state *state) {
state->hi = (state->hi << 16) + (state->hi >> 16);
state->hi += state->lo;
state->lo += state->hi;
return state->hi;
}
void randomize_buffer() {
size_t size = (length() * sizeof(T)) / sizeof(*_pData);
struct random_state state = { 2147483563, 2147483563 ^ 0x49616E42 };
for (size_t i = 0; i < size; i++) {
_pData[i] = my_random(&state);
}
}
public:
using const_pointer = const T *;
using const_reference = const T&;
using const_iterator = const_pointer;
random_numerators() {
#if defined(__AVR__)
// Using 1/8 of free RAM should be enough to fool the
// compiler optimizer and give enough test iterations on
// AVR hardware
_length = (freeRAM()/8)/sizeof(T);
#else
_length = 1 << 19;
// Make sure that the number of iterations is not
// known at compile time to prevent the compiler
// from magically calculating results at compile
// time and hence falsifying the benchmark.
srand((unsigned)time(NULL));
_length += (rand() % 3) * (1 << 10);
#endif
_pData = allocate(_length * sizeof(T));
randomize_buffer();
}
~random_numerators() {
deallocate(_pData);
}
const_iterator begin() const { return (const_pointer)_pData; }
const_iterator end() const { return begin()+length(); }
uint32_t length() const { return _length; }
};