Skip to content

Commit

Permalink
Use xoroshiro128+ random generator (everywhere besides BSON code).
Browse files Browse the repository at this point in the history
  • Loading branch information
savask committed Apr 23, 2018
1 parent fbe81ba commit cda029f
Show file tree
Hide file tree
Showing 93 changed files with 481 additions and 406 deletions.
6 changes: 1 addition & 5 deletions src/Probability.cpp
Expand Up @@ -16,6 +16,7 @@
#include <numeric>
#include <cstdlib>
#include "Probability.h"
#include "common/tpt-rand.h"

namespace Probability
{
Expand All @@ -25,11 +26,6 @@ float binomial_gte1(int n, float p)
return 1.0f - std::pow(1.0f-p, n);
}

float randFloat()
{
return static_cast<float>(rand())/RAND_MAX;
}

SmallKBinomialGenerator::SmallKBinomialGenerator(unsigned int n, float p, unsigned int maxK_)
{
maxK = maxK_;
Expand Down
1 change: 0 additions & 1 deletion src/Probability.h
Expand Up @@ -25,7 +25,6 @@ namespace Probability
// X ~ binomial(n,p), returns P(X>=1)
// e.g. If a reaction has n chances of occurring, each time with probability p, this returns the probability that it occurs at least once.
float binomial_gte1(int n, float p);
float randFloat();

class SmallKBinomialGenerator
{
Expand Down
51 changes: 51 additions & 0 deletions src/common/tpt-rand.cpp
@@ -0,0 +1,51 @@
#include "tpt-rand.h"
#include <cstdlib>

/* xoroshiro128+ by David Blackman and Sebastiano Vigna */

static inline uint64_t rotl(const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}

uint64_t RandomGen::next(void) {
const uint64_t s0 = s[0];
uint64_t s1 = s[1];
const uint64_t result = s0 + s1;

s1 ^= s0;
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
s[1] = rotl(s1, 36); // c

return result;
}

unsigned int RandomGen::operator()()
{
return next()&0xFFFFFFFF;
}

unsigned int RandomGen::between(unsigned int lower, unsigned int upper)
{
unsigned int r = (*this)();

return r % (upper - lower + 1) + lower;
}

float RandomGen::uniform01()
{
return static_cast<float>(random_gen())/(float)0xFFFFFFFF;
}

RandomGen::RandomGen()
{
s[0] = 1;
s[1] = 2;
}

void RandomGen::seed(unsigned int sd)
{
s[0] = sd;
s[1] = sd;
}

RandomGen random_gen;
22 changes: 22 additions & 0 deletions src/common/tpt-rand.h
@@ -0,0 +1,22 @@
#ifndef TPT_RAND_
#define TPT_RAND_

#include <stdint.h>

class RandomGen
{
private:
uint64_t s[2];
uint64_t next(void);
public:
unsigned int operator()();
unsigned int between(unsigned int lower, unsigned int upper);
float uniform01();

RandomGen();
void seed(unsigned int sd);
};

extern RandomGen random_gen;

#endif /* TPT_RAND_ */
7 changes: 4 additions & 3 deletions src/graphics/Renderer.cpp
Expand Up @@ -8,6 +8,7 @@
#include "Renderer.h"
#include "Graphics.h"
#include "common/tpt-math.h"
#include "common/tpt-rand.h"
#include "common/tpt-minmax.h"
#include "gui/game/RenderPreset.h"
#include "simulation/Elements.h"
Expand Down Expand Up @@ -1774,7 +1775,7 @@ void Renderer::render_parts()
}
if(pixel_mode & PMODE_SPARK)
{
flicker = rand()%20;
flicker = random_gen()%20;
#ifdef OGLR
//Oh god, this is awful
lineC[clineC++] = ((float)colr)/255.0f;
Expand Down Expand Up @@ -1838,7 +1839,7 @@ void Renderer::render_parts()
}
if(pixel_mode & PMODE_FLARE)
{
flicker = rand()%20;
flicker = random_gen()%20;
#ifdef OGLR
//Oh god, this is awful
lineC[clineC++] = ((float)colr)/255.0f;
Expand Down Expand Up @@ -1911,7 +1912,7 @@ void Renderer::render_parts()
}
if(pixel_mode & PMODE_LFLARE)
{
flicker = rand()%20;
flicker = random_gen()%20;
#ifdef OGLR
//Oh god, this is awful
lineC[clineC++] = ((float)colr)/255.0f;
Expand Down
6 changes: 4 additions & 2 deletions src/gui/preview/PreviewView.cpp
Expand Up @@ -17,6 +17,8 @@
#include "gui/interface/AvatarButton.h"
#include "gui/interface/Keys.h"
#include "gui/dialogues/ErrorMessage.h"
#include "common/tpt-math.h"
#include "common/tpt-rand.h"

class PreviewView::LoginAction: public ui::ButtonAction
{
Expand Down Expand Up @@ -297,7 +299,7 @@ void PreviewView::CheckComment()
{
if (!commentHelpText)
{
if (rand()%2)
if (random_gen()%2)
commentWarningLabel->SetText("Stolen? Report the save instead");
else
commentWarningLabel->SetText("Please report stolen saves");
Expand All @@ -313,7 +315,7 @@ void PreviewView::CheckComment()
{
if (!commentHelpText)
{
if (rand()%2)
if (random_gen()%2)
commentWarningLabel->SetText("Please do not swear");
else
commentWarningLabel->SetText("Bad language may be deleted");
Expand Down
3 changes: 2 additions & 1 deletion src/simulation/Air.cpp
Expand Up @@ -6,6 +6,7 @@
//#include <powder.h>
//#include <defines.h>
#include "Gravity.h"
#include "common/tpt-rand.h"

/*float kernel[9];
Expand Down Expand Up @@ -373,7 +374,7 @@ void Air::RecalculateBlockAirMaps()
}
}
// mostly accurate insulator blocking, besides checking GEL
else if ((type == PT_HSWC && sim.parts[i].life != 10) || sim.elements[type].HeatConduct <= (rand()%250))
else if ((type == PT_HSWC && sim.parts[i].life != 10) || sim.elements[type].HeatConduct <= (random_gen()%250))
{
int x = ((int)(sim.parts[i].x+0.5f))/CELL, y = ((int)(sim.parts[i].y+0.5f))/CELL;
if (sim.InBounds(x, y) && !(bmap_blockairh[y][x]&0x8))
Expand Down
1 change: 1 addition & 0 deletions src/simulation/Elements.h
Expand Up @@ -70,6 +70,7 @@
struct playerst;

#include "ElementClasses.h"
#include "common/tpt-rand.h"


#endif /* ELEMENTS_H_ */

2 comments on commit cda029f

@moonheart08
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

@moonheart08
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that's nice. next(), when compiled in release mode, is 14 instructions (at least on my laptop)

mov    (%rdi),%rax
mov    0x8(%rdi),%rsi
mov    %rax,%rdx
rorx   $0x9,%rax,%rcx
add    %rsi,%rax
xor    %rsi,%rdx
mov    %rdx,%r8
xor    %rdx,%rcx
rorx   $0x1c,%rdx,%rdx
shl    $0xe,%r8
mov    %rdx,0x8(%rdi)
xor    %r8,%rcx
mov    %rcx,(%rdi)
retq   

All low level, high speed instructions. Plus, almost everything it does is directly operating on registers, not memory, making it even faster (1-2 uOPs).
Only thing that should be different for standard builds is RORX not being there, as RORX is a newer instruction and as such less systems have it.

Please sign in to comment.