提交 5f8ad95c 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

use a strong prng like arc4.

out of ~1000000 invocations: rnd.cc generates 999426 odd and 510 even numbers arc4.hh generates 500412 odd and 499508 even numbers
上级 0e6651e8
class arc4 {
public:
arc4(const u8 *key, size_t nbytes) {
reset();
for (size_t n = 0; n < nbytes; n += 128)
addkey(&key[n], nbytes > n + 128 ? 128 : n + 128 - nbytes);
j = i;
}
u8 getbyte() {
uint8_t si, sj;
i = (i + 1) & 0xff;
si = s[i];
j = (j + si) & 0xff;
sj = s[j];
s[i] = sj;
s[j] = si;
return s[(si + sj) & 0xff];
}
template<class T> T rand() {
T v;
for (u32 i = 0; i < sizeof(v); i++)
*(u8*) &v = getbyte();
return v;
}
private:
void reset() {
i = 0xff;
j = 0;
for (u32 n = 0; n < 0x100; n++)
s[n] = n;
}
void addkey(const u8 *key, size_t nbytes) {
size_t n, keypos;
uint8_t si;
for (n = 0, keypos = 0; n < 256; n++, keypos++) {
if (keypos >= nbytes)
keypos = 0;
i = (i + 1) & 0xff;
si = s[i];
j = (j + si + key[keypos]) & 0xff;
s[i] = s[j];
s[j] = si;
}
}
u8 i;
u8 j;
u8 s[256];
};
......@@ -10,6 +10,8 @@ extern "C" {
#include <string.h>
}
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef uintptr_t uptr;
......
......@@ -7,9 +7,11 @@
#include "crange.hh"
#include "atomic_util.hh"
#include "ns.hh"
#include "rnd.hh"
#include "scopedperf.hh"
#include "intelctr.hh"
#include "arc4.hh"
#include "amd64.h"
#include "rnd.hh"
u64
proc_hash(const u32 &pid)
......@@ -17,12 +19,25 @@ proc_hash(const u32 &pid)
return pid;
}
pthread_key_t myproc_key;
pthread_key_t myproc_key, arc4_key;
cpu cpus[NCPU];
u32 ncpu;
u64 ticks;
xns<u32, proc*, proc_hash> *xnspid;
template<class T>
T rnd()
{
arc4 *a = (arc4*) pthread_getspecific(arc4_key);
if (!a) {
struct seed { u64 a, b; } s = { rdtsc(), pthread_self() };
a = new arc4((u8*) &s, sizeof(s));
pthread_setspecific(arc4_key, a);
}
return a->rand<T>();
}
static void*
proc_start(void *arg)
{
......@@ -74,9 +89,9 @@ worker(void *arg)
for (u32 i = 0; i < iter_total / ncpu; i++) {
ANON_REGION("worker op", &perfgroup);
u64 k = 1 + rnd() % (crange_items * 2);
u64 k = 1 + rnd<u32>() % (crange_items * 2);
auto span = cr->search_lock(k, 1);
if (rnd() & 1) {
if (rnd<u8>() & 1) {
ANON_REGION("worker del", &perfgroup);
span.replace(0);
} else {
......@@ -145,6 +160,7 @@ main(int ac, char **av)
}
assert(0 == pthread_key_create(&myproc_key, 0));
assert(0 == pthread_key_create(&arc4_key, 0));
for (u32 i = 0; i < NCPU; i++)
cpus[i].id = i;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论