Skip to content

Commit 414d7b3

Browse files
committed
Implement xoroshiro random number generator
Implementation of xoroshiro, another kind of PRNG. About the detailed concept of the algorithm please refer to the paper "Scrambled Linear Pseudorandom Number Generators". We implement this algorithm in order to replace the wyhash algorithm used in MCTS simulation step. Note that we're using the ++scrambler in the xoro_next() function.
1 parent 29856ae commit 414d7b3

File tree

6 files changed

+79
-4
lines changed

6 files changed

+79
-4
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
TARGET = kmldrv
2-
kmldrv-objs = simrupt.o game.o wyhash.o mcts.o negamax.o zobrist.o
2+
kmldrv-objs = simrupt.o game.o wyhash.o xoroshiro.o mcts.o negamax.o zobrist.o
33
obj-m := $(TARGET).o
44

55
ccflags-y := -std=gnu99 -Wno-declaration-after-statement

mcts.c

+12-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
#include "game.h"
55
#include "mcts.h"
66
#include "util.h"
7-
#include "wyhash.h"
7+
// #include "wyhash.h"
8+
#include "xoroshiro.h"
89

910
struct node {
1011
int move;
@@ -15,6 +16,8 @@ struct node {
1516
struct node *children[N_GRIDS];
1617
};
1718

19+
static struct state_array xoro_obj;
20+
1821
static struct node *new_node(int move, char player, struct node *parent)
1922
{
2023
struct node *node = kzalloc(sizeof(struct node), GFP_KERNEL);
@@ -122,6 +125,7 @@ static fixed_point_t simulate(char *table, char player)
122125
char current_player = player;
123126
char temp_table[N_GRIDS];
124127
memcpy(temp_table, table, N_GRIDS);
128+
xoro_jump(&xoro_obj);
125129
while (1) {
126130
int *moves = available_moves(temp_table);
127131
if (moves[0] == -1) {
@@ -131,7 +135,8 @@ static fixed_point_t simulate(char *table, char player)
131135
int n_moves = 0;
132136
while (n_moves < N_GRIDS && moves[n_moves] != -1)
133137
++n_moves;
134-
int move = moves[wyhash64() % n_moves];
138+
// int move = moves[wyhash64() % n_moves];
139+
int move = moves[xoro_next(&xoro_obj) % n_moves];
135140
kfree(moves);
136141
temp_table[move] = current_player;
137142
char win;
@@ -204,3 +209,8 @@ int mcts(char *table, char player)
204209
free_node(root);
205210
return best_move;
206211
}
212+
213+
void mcts_init(void)
214+
{
215+
xoro_init(&xoro_obj);
216+
}

mcts.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
#define ITERATIONS 100000
44
#define EXPLORATION_FACTOR fixed_sqrt(1U << (FIXED_SCALE_BITS + 1))
55

6-
int mcts(char *table, char player);
6+
int mcts(char *table, char player);
7+
void mcts_init(void);

simrupt.c

+1
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ static int __init kmldrv_init(void)
515515
}
516516

517517
negamax_init();
518+
mcts_init();
518519
memset(table, ' ', N_GRIDS);
519520
turn = 'O';
520521
finish = 1;

xoroshiro.c

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
#include "xoroshiro.h"
3+
4+
static inline u64 rotl(const u64 x, int k)
5+
{
6+
return (x << k) | (x >> (64 - k));
7+
}
8+
9+
static inline void seed(struct state_array *obj, u64 s0, u64 s1)
10+
{
11+
obj->array[0] = s0;
12+
obj->array[1] = s1;
13+
}
14+
15+
u64 xoro_next(struct state_array *obj)
16+
{
17+
const u64 s0 = obj->array[0];
18+
u64 s1 = obj->array[1];
19+
const u64 result = rotl(s0 + s1, 24) + s0;
20+
21+
s1 ^= s0;
22+
obj->array[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16);
23+
obj->array[1] = rotl(s1, 37);
24+
25+
return result;
26+
}
27+
28+
void xoro_jump(struct state_array *obj)
29+
{
30+
static const u64 JUMP[] = {0xdf900294d8f554a5, 0x170865df4b3201fc};
31+
32+
u64 s0 = 0;
33+
u64 s1 = 0;
34+
int i, b;
35+
for (i = 0; i < sizeof(JUMP) / sizeof(*JUMP); i++) {
36+
for (b = 0; b < 64; b++) {
37+
if (JUMP[i] & (u64) (1) << b) {
38+
s0 ^= obj->array[0];
39+
s1 ^= obj->array[1];
40+
}
41+
xoro_next(obj);
42+
}
43+
}
44+
45+
obj->array[0] = s0;
46+
obj->array[1] = s1;
47+
}
48+
49+
void xoro_init(struct state_array *obj)
50+
{
51+
seed(obj, 314159265, 1618033989);
52+
}

xoroshiro.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
#include <linux/slab.h>
4+
5+
struct state_array {
6+
u64 array[2];
7+
};
8+
9+
u64 xoro_next(struct state_array *obj);
10+
void xoro_jump(struct state_array *obj);
11+
void xoro_init(struct state_array *obj);

0 commit comments

Comments
 (0)