Skip to content

Commit

Permalink
1.37s -> 1.14s. Store 2 skips in 1 byte
Browse files Browse the repository at this point in the history
  • Loading branch information
Jumbub committed Mar 20, 2022
1 parent 34755bb commit 07ca8c5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 21 deletions.
5 changes: 5 additions & 0 deletions src/logic/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@
using uint = unsigned int;
using ulong = unsigned long;
using Cell = uint8_t;

[[maybe_unused]] const Cell ALIVE = 1;
[[maybe_unused]] const Cell DEAD = 0;

[[maybe_unused]] const Cell SKIP_2 = (1 << 1) + (1 << 2);
[[maybe_unused]] const Cell SKIP_1 = (1 << 2);
[[maybe_unused]] const Cell SKIP_0 = 0;

constexpr unsigned int PADDING = 2; // Padding of board left+right or top+bottom.

struct Board {
Expand Down
26 changes: 13 additions & 13 deletions src/logic/next.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ constexpr uint8_t LOOKUP[20] = {
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
};

const uint64_t SKIP_EIGHT =
(1 << 0) + (1 << 8) + (1 << 16) + (1 << 24) + (1l << 32) + (1l << 40) + (1l << 48) + (1l << 56);
const uint64_t SKIP_SIXTEEN = (SKIP_2 << 0) + (SKIP_2 << 8) + (SKIP_2 << 16) + (SKIP_2 << 24) + ((long)SKIP_2 << 32) +
((long)SKIP_2 << 40) + ((long)SKIP_2 << 48) + ((long)SKIP_2 << 56);

uint isAlive(const uint& i, const Cell* input, const uint& realWidth) {
const Cell* top = &input[i - realWidth - 1];
Expand All @@ -32,9 +32,9 @@ uint isAlive(const uint& i, const Cell* input, const uint& realWidth) {
}

inline void revokeSkipForNeighbours(const uint& i, Cell* skips, const uint& realWidth) {
*reinterpret_cast<uint32_t*>(&skips[i - realWidth - 1]) = false;
*reinterpret_cast<uint32_t*>(&skips[i - 1]) = false;
*reinterpret_cast<uint32_t*>(&skips[i + realWidth - 1]) = false;
*reinterpret_cast<uint32_t*>(&skips[(i - realWidth - 1) / 2]) = SKIP_0;
*reinterpret_cast<uint32_t*>(&skips[(i - 1) / 2]) = SKIP_0;
*reinterpret_cast<uint32_t*>(&skips[(i + realWidth - 1) / 2]) = SKIP_0;
}

void nextBoardSection(
Expand All @@ -46,8 +46,8 @@ void nextBoardSection(
uint8_t* inSkip,
uint8_t* outSkip) {
while (i < endI) {
while (uint8s_to_uint64(&inSkip[i]) == SKIP_EIGHT)
i += 8;
while (uint8s_to_uint64(&inSkip[i / 2]) == SKIP_SIXTEEN)
i += 16;

output[i] = isAlive(i, input, realWidth);

Expand Down Expand Up @@ -82,28 +82,28 @@ void nextBoard(Board& board, const uint& threadCount, const uint& jobCount) {
const auto& beginI = std::get<0>(segments[i]);
const auto& endI = std::get<1>(segments[i]);

board.inSkip[endI] = false; // Never skip last cell

// Reset next border
if (i == jobCount - 1) {
std::memset(&board.outSkip[endI - board.rawWidth], true, board.rawSize - (endI - board.rawWidth));
std::memset(&board.outSkip[(endI - board.rawWidth) / 2], SKIP_2, (board.rawSize - (endI - board.rawWidth)) / 2);
} else {
const auto borderSize = std::min(board.rawSize, endI + board.rawWidth * 3);
std::memset(&board.outSkip[endI - board.rawWidth], true, borderSize - endI);
std::memset(&board.outSkip[endI - board.rawWidth], SKIP_2, (borderSize - endI) / 2);
}

jobs[i] = [&, beginI, endI]() {
// Reset inner skips
if (endI == beginI)
return;
const auto max = std::max(beginI + board.rawWidth, endI - board.rawWidth);
std::memset(&board.outSkip[beginI + board.rawWidth], true, max - beginI - board.rawWidth);
std::memset(&board.outSkip[(beginI + board.rawWidth) / 2], SKIP_2, (max - beginI - board.rawWidth) / 2);
nextBoardSection(beginI + 1, endI - 1, board.rawWidth, board.input, board.output, board.inSkip, board.outSkip);
};

board.inSkip[endI] = SKIP_0; // Never skip last cell of segment
};

// Reset first border
std::memset(board.outSkip, true, sizeof(Cell) * board.rawWidth);
std::memset(board.outSkip, SKIP_2, (sizeof(Cell) * board.rawWidth) / 2);

std::atomic<uint> job = {0};
std::vector<std::thread> threads(threadCount - 1);
Expand Down
16 changes: 8 additions & 8 deletions src/logic/padding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@ void assignSkips(Cell* cells, uint innerWidth, uint innerHeight) {
const uint height = innerHeight + PADDING;

for (uint i = 1; i <= width - 1; i++) {
cells[i + width * innerHeight] = cells[i + width * innerHeight] & cells[i];
cells[(i + width * innerHeight) / 2] = SKIP_0;
}
for (uint i = width * (height - 1) + 1; i <= width * height - 2; i++) {
cells[i - width * innerHeight] = cells[i - width * innerHeight] & cells[i];
cells[(i - width * innerHeight) / 2] = SKIP_0;
}
for (uint i = width; i <= width * (height - 1); i += width) {
cells[i + innerWidth] = cells[i + innerWidth] & cells[i];
cells[(i + innerWidth) / 2] = SKIP_0;
}
for (uint i = (width * 2) - 1; i <= width * (height - 1) - 1; i += width) {
cells[i - innerWidth] = cells[i - innerWidth] & cells[i];
cells[(i - innerWidth) / 2] = SKIP_0;
}
cells[0] = cells[0] & cells[width * (height - 1) - 2];
cells[width - 1] = cells[width - 1] & cells[width * (height - 2) + 1];
cells[width * (height - 1)] = cells[width * (height - 1)] & cells[width * 2 - 2];
cells[width * height - 1] = cells[width * height - 1] & cells[width + 1];
cells[(0) / 2] = SKIP_0;
cells[(width - 1) / 2] = SKIP_0;
cells[(width * (height - 1)) / 2] = SKIP_0;
cells[(width * height - 1) / 2] = SKIP_0;
}

void assignBoardPadding(Board& board) {
Expand Down

0 comments on commit 07ca8c5

Please sign in to comment.