Skip to content

Commit

Permalink
92ms -> 55ms. Cache the y level computations
Browse files Browse the repository at this point in the history
  • Loading branch information
Jumbub committed Oct 3, 2021
1 parent 687ed50 commit 9e80c59
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .vimspector.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"adapter": "vscode-cpptools",
"configuration": {
"request": "launch",
"program": "build/interactive",
"program": "build/out",
"MIMode": "gdb",
"MIDebuggerPath": "/usr/bin/gdb",
"extrenalConsole": true
Expand Down
8 changes: 4 additions & 4 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ COMPILER_FLAGS_DEBUG = $(COMPILER_FLAGS) -ggdb

LINKER_FLAGS_GRAPHICS = -lSDL2

OUTPUT = build/interactive
OUTPUT_BENCHMARK = build/benchmark
OUTPUT_DEBUG = build/debug
OUTPUT_TEST = build/test
OUTPUT = build/out
OUTPUT_BENCHMARK = build/out
OUTPUT_DEBUG = build/out
OUTPUT_TEST = build/out

OBJS = src/util/profile.cpp src/board/next.cpp src/board/generate.cpp
OBJS_GRAPHICS = $(OBJS) src/board/sdl.cpp
Expand Down
4 changes: 2 additions & 2 deletions results/benchmark.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
----------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------
BM_NextBoard/min_time:5.000 88.3 ms 88.2 ms 75
BM_RenderNextBoard/min_time:5.000 92.4 ms 92.4 ms 70
BM_NextBoard/min_time:5.000 49.9 ms 49.5 ms 127
BM_RenderNextBoard/min_time:5.000 55.1 ms 55.0 ms 110
73 changes: 38 additions & 35 deletions src/board/next.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,6 @@
#include <tuple>
#include <vector>

void computeNeighbourColumns(char (&counts)[3], const Board &board, const int &x,
const int &y) {
const auto &[input, width, height] = board;

for (int ox = -1; ox <= 1; ox++) {
counts[ox + 1] = 0;
for (int oy = -1; oy <= 1; oy++) {
// Do not count self
if (oy == 0 && ox == 0)
continue;

// Real offset calculations
const auto rox = (ox + x + width) % width;
const auto roy = (oy + y + height) % height;

if (input[roy * width + rox] == ALIVE)
counts[ox + 1]++;
}
}
}

Board nextBoard(const Board &board) {
const auto &[input, width, height] = board;
if (height == 0)
Expand All @@ -36,32 +15,56 @@ Board nextBoard(const Board &board) {

auto output = new Cell[width * height];

char neighbours[3] = {0, 0, 0};
int neighbours[3];
int yAboveBase;
int yBelowBase;
int yBase;

for (int i = 0; i < width * height; i++) {
const int x = i % width;
const int y = i / width;
auto currentState = input[i];
auto currentStateBool = input[i] == ALIVE ? 1 : 0;

// Compute neighbour columns
// Slide neighbours
if (x == 0) {
computeNeighbourColumns(neighbours, board, x, y);
// Clear neighbour columns
neighbours[0] = -1;
neighbours[1] = -1;
neighbours[2] = -1;

// Compute new Y levels
const int y = i / width;
yBase = y * width;
yBelowBase = ((y - 1 + height) % height) * width;
yAboveBase = ((y + 1) % height) * width;
} else {
// Shift neighbour columns down
// Remove self from right neighbour column
neighbours[2] -= currentStateBool;

// Shift neighbour columns
neighbours[0] = neighbours[1];
neighbours[1] = neighbours[2];
neighbours[2] = 0;
neighbours[2] = -1;
}

// Remove self from neighbours
neighbours[1] -= currentStateBool;
// Compute neighbours
if (neighbours[0] == -1) {
const auto previousX = (x - 1 + width) % width;

neighbours[0] = (input[yBelowBase + previousX] ? 1 : 0) +
(input[yBase + previousX] ? 1 : 0) +
(input[yAboveBase + previousX] ? 1 : 0);
}
if (neighbours[1] == -1) {
neighbours[1] = (input[yBelowBase + x] ? 1 : 0) +
(input[yAboveBase + x] ? 1 : 0);
}
if (neighbours[2] == -1) {
const auto nextX = (x + 1) % width;

// Compute next column of neighbours
const int nextX = (x + 1) % width;
for (int offsetY = -1; offsetY <= 1; offsetY++) {
const int neighbourI = nextX + ((y + offsetY + height) % height) * width;
neighbours[2] += input[neighbourI] == ALIVE ? 1 : 0;
}
neighbours[2] = (input[yBelowBase + nextX] ? 1 : 0) +
(input[yBase + nextX] ? 1 : 0) +
(input[yAboveBase + nextX] ? 1 : 0);
}

// Compute new cell state
Expand Down

0 comments on commit 9e80c59

Please sign in to comment.