Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use faster XOR shift RNG. #9

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@
# csharp
/bin
/obj


# Added by cargo

/target
4 changes: 2 additions & 2 deletions build-clang.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env sh

mkdir -p build/clang
gcc -O3 -o build/clang/almost_pseudo_random src/main/c/almost_pseudo_random.c -lm
gcc -O3 -o build/clang/java_2_times_faster_than_c src/main/c/java_2_times_faster_than_c.c -lm
clang -O3 -march=native -o build/clang/xorshift_rng src/main/c/xorshift_rng.c
clang -O3 -march=native -o build/clang/java_2_times_faster_than_c src/main/c/java_2_times_faster_than_c.c -lm
3 changes: 2 additions & 1 deletion build-csharp.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env sh

mkdir -p build/csharp
dotnet publish -c Release -o ./build/csharp ./src/main/csharp/java-4-times-faster-than-c-sharp.csproj
dotnet publish -c Release -o ./build/csharp ./src/main/csharp/java-faster-csharp/java-faster-csharp.csproj
dotnet publish -c Release -o ./build/csharp ./src/main/csharp/xorshift_rng/xorshift_rng.csproj
4 changes: 2 additions & 2 deletions build-gcc.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env sh

mkdir -p build/gcc
gcc -O3 -o build/gcc/almost_pseudo_random src/main/c/almost_pseudo_random.c -lm
gcc -O3 -o build/gcc/java_2_times_faster_than_c src/main/c/java_2_times_faster_than_c.c -lm
gcc -O3 -march=native -o build/gcc/xorshift_rng src/main/c/xorshift_rng.c
gcc -O3 -march=native -o build/gcc/java_2_times_faster_than_c src/main/c/java_2_times_faster_than_c.c -lm
2 changes: 1 addition & 1 deletion build-go.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

mkdir -p build/go
go build -o ./build/go/java_faster_than_go ./src/main/go/java_faster_than_go.go
go build -o ./build/go/almost_pseudo_random ./src/main/go/almost_pseudo_random.go
go build -o ./build/go/xorshift_rng ./src/main/go/xorshift_rng.go
6 changes: 0 additions & 6 deletions build-rs.sh

This file was deleted.

9 changes: 9 additions & 0 deletions build-rust.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env sh

mkdir -p build/rust
cargo build --release --manifest-path src/main/rust/Cargo.toml
find src/main/rust/target/release \
-maxdepth 1 \
-executable \
-type f \
-exec cp -f {} build/rust \;
44 changes: 31 additions & 13 deletions src/main/c/java_2_times_faster_than_c.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright 2021 Kazimierz Pogoda
* Copyright 2021 Sam Leonard
*
* This file is part of java-2-times-faster-than-c.
*
Expand All @@ -18,6 +19,7 @@
*/

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>

Expand All @@ -26,6 +28,24 @@ const int INITIAL_NODE_COUNT = 10000;
const long MUTATION_COUNT = 1000000L;
const int MAX_MUTATION_SIZE = 200;

struct xorshift64s_state {
uint64_t a;
};

double xorshift64s(struct xorshift64s_state *state) {
uint64_t x = state->a; /* The state must be seeded with a nonzero value. */
x ^= x >> 12; // a
x ^= x << 25; // b
x ^= x >> 27; // c
state->a = x;
uint64_t rand_val = x * UINT64_C(0x2545F4914F6CDD1D);

// mix to a double
uint32_t a = rand_val >> 32;
uint32_t b = rand_val & 0xFFFFFFFF;
return ((a >> 5) * 67108864.0 + (b >> 6)) * (1.0 / 9007199254740991.0);
}

typedef struct Node Node;

struct Node {
Expand All @@ -36,12 +56,8 @@ struct Node {
Node *next;
} NodeDef;

double almost_pseudo_random(long ordinal) {
return fmod((sin(((double) ordinal) * 100000.0) + 1.0), 1.0);
}

Node *new_node(long id) {
int size = (int) (almost_pseudo_random(id) * MAX_PAYLOAD_SIZE);
Node *new_node(long id, struct xorshift64s_state * rng_state) {
int size = (int) (xorshift64s(rng_state) * MAX_PAYLOAD_SIZE);
int charId = (char) id;
Node *node = malloc(sizeof(NodeDef));
node->id = id;
Expand Down Expand Up @@ -77,15 +93,17 @@ void insert(Node *previous, Node *node) {

int main() {
long node_id = 0;
long mutation_seq = 0;
Node *head = new_node(node_id++);
join(head, new_node(node_id++));
struct xorshift64s_state rng_state = {
.a = 42,
};
Node *head = new_node(node_id++, &rng_state);
join(head, new_node(node_id++, &rng_state));
for (int i = 2; i < INITIAL_NODE_COUNT; i++) {
insert(head, new_node(node_id++));
insert(head, new_node(node_id++, &rng_state));
}
long node_count = INITIAL_NODE_COUNT;
for (long i = 0; i < MUTATION_COUNT; i++) {
int delete_count = (int) (almost_pseudo_random(mutation_seq++) * (double) MAX_MUTATION_SIZE);
int delete_count = (int) (xorshift64s(&rng_state) * (double) MAX_MUTATION_SIZE);
if (delete_count > (node_count - 2)) {
delete_count = (int) node_count - 2;
}
Expand All @@ -95,9 +113,9 @@ int main() {
delete(to_delete);
}
node_count -= delete_count;
int insert_count = (int) (almost_pseudo_random(mutation_seq++) * (double) MAX_MUTATION_SIZE);
int insert_count = (int) (xorshift64s(&rng_state) * (double) MAX_MUTATION_SIZE);
for (int j = 0; j < insert_count; j++) {
insert(head, new_node(node_id++));
insert(head, new_node(node_id++, &rng_state));
head = head->next;
}
node_count += insert_count;
Expand Down
39 changes: 29 additions & 10 deletions src/main/c/almost_pseudo_random.c → src/main/c/xorshift_rng.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Kazimierz Pogoda
* Copyright 2021 Sam Leonard
*
* This file is part of java-2-times-faster-than-c.
*
Expand All @@ -18,18 +18,37 @@
*/

#include <stdio.h>
#include <math.h>
#include <stdint.h>

const long ITERATION_COUNT = 1000000000L;

double almost_pseudo_random(long ordinal) {
return fmod(sin(((double) ordinal) * 100000.0) + 1.0, 1.0);
struct xorshift64s_state {
uint64_t a;
};

double xorshift64s(struct xorshift64s_state *state) {
uint64_t x = state->a; /* The state must be seeded with a nonzero value. */
x ^= x >> 12; // a
x ^= x << 25; // b
x ^= x >> 27; // c
state->a = x;
uint64_t rand_val = x * UINT64_C(0x2545F4914F6CDD1D);

// mix to a double
uint32_t a = rand_val >> 32;
uint32_t b = rand_val & 0xFFFFFFFF;

return ((a >> 5) * 67108864.0 + (b >> 6)) * (1.0 / 9007199254740991.0);
}

void main() {
double checksum = 0;
for (long i = 0; i < ITERATION_COUNT; i++) {
checksum += almost_pseudo_random(i);
}
printf("checksum: %f\n", checksum);
int main(void) {
struct xorshift64s_state rng_state = {
.a = 42
};

double checksum = 0;
for (long i = 0; i < ITERATION_COUNT; i++) {
checksum += xorshift64s(&rng_state);
}
printf("checksum: %f\n", checksum);
}
4 changes: 2 additions & 2 deletions src/main/csharp/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/bin
/obj
bin/
obj/
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System;
using System.Linq;
using XorShift;

namespace csharp
{
static class Program
{

private const int MaxPayloadSize = 50;
private const int InitialNodeCount = 10000;
private const long MutationCount = 1000000L;
Expand All @@ -18,10 +18,10 @@ class Node
public long Id { get; }
public byte[] Payload { get; }

public Node(long id)
public Node(long id, XorShift64SRng rng)
{
Id = id;
int size = (int) (AlmostPseudoRandom(id) * (double) MaxPayloadSize);
int size = (int) (rng.getRand() * (double) MaxPayloadSize);
byte[] data = new byte[size];
for (int i = 0; i < size; i++)
{
Expand Down Expand Up @@ -58,26 +58,21 @@ public void Insert(Node node)
}
}

private static double AlmostPseudoRandom(long ordinal)
{
return (Math.Sin(((double) ordinal) * 100000.0) + 1.0) % 1.0;
}

static void Main(string[] args)
{
long nodeId = 0;
long mutationSeq = 0;
var head = new Node(nodeId++);
head.Join(new Node(nodeId++));
XorShift64SRng rng = new XorShift64SRng(42);
var head = new Node(nodeId++, rng);
head.Join(new Node(nodeId++, rng));
for (var i = 2; i < InitialNodeCount; i++)
{
head.Insert(new Node(nodeId++));
head.Insert(new Node(nodeId++, rng));
}

long nodeCount = InitialNodeCount;
for (long i = 0; i < MutationCount; i++)
{
var deleteCount = (int) (AlmostPseudoRandom(mutationSeq++) * (double) MaxMutationSize);
var deleteCount = (int) (rng.getRand() * (double) MaxMutationSize);
if (deleteCount > (nodeCount - 2))
{
deleteCount = (int) nodeCount - 2;
Expand All @@ -91,10 +86,10 @@ static void Main(string[] args)
}

nodeCount -= deleteCount;
var insertCount = (int) (AlmostPseudoRandom(mutationSeq++) * (double) MaxMutationSize);
var insertCount = (int) (rng.getRand() * (double) MaxMutationSize);
for (int j = 0; j < insertCount; j++)
{
head.Insert(new Node(nodeId++));
head.Insert(new Node(nodeId++, rng));
head = head.Next;
}

Expand All @@ -119,4 +114,4 @@ static void Main(string[] args)
Console.WriteLine("checksum: " + checksum);
}
}
}
}
13 changes: 13 additions & 0 deletions src/main/csharp/java-faster-csharp/java-faster-csharp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="../xorshift_rng/xorshift_rng.csproj" />
</ItemGroup>

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>csharp</RootNamespace>
</PropertyGroup>

</Project>
22 changes: 22 additions & 0 deletions src/main/csharp/xorshift_rng/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Linq;

namespace XorShift
{
static class Program
{
private const ulong ITERATION_COUNT = 1000000000L;

static void Main(string[] args)
{
double checksum = 0;
XorShift64SRng rng = new XorShift64SRng(42);
for (uint i = 0; i < ITERATION_COUNT; i++)
{
checksum += rng.getRand();
}

Console.WriteLine($"checksum: {checksum}");
}
}
}
32 changes: 32 additions & 0 deletions src/main/csharp/xorshift_rng/XorShift64SRng.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Linq;

namespace XorShift
{
public class XorShift64SRng
{
private ulong State;

public XorShift64SRng(ulong state)
{
State = state;
}

public double getRand()
{
ulong x = State;
x ^= x >> 12; // a
x ^= x << 25; // b
x ^= x >> 27; // c
State = x;

ulong rand_val = x * 0x2545F4914F6CDD1DL;

// mix to a double
uint a = (uint) (rand_val >> 32);
uint b = (uint) rand_val;

return ((double) (a >> 5) * 67108864.0 + (double) (b >> 6)) * (1.0 / 9007199254740991.0);
}
}
}
Loading