Go to file
2023-10-17 14:19:03 +02:00
.gitignore Initial commit. 2023-10-17 14:19:03 +02:00
2**20.png Initial commit. 2023-10-17 14:19:03 +02:00
2**21.png Initial commit. 2023-10-17 14:19:03 +02:00
2**22.png Initial commit. 2023-10-17 14:19:03 +02:00
2**24.png Initial commit. 2023-10-17 14:19:03 +02:00
check.sh Initial commit. 2023-10-17 14:19:03 +02:00
common.c Initial commit. 2023-10-17 14:19:03 +02:00
README.md Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_1d_100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_1d-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_1d.c Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_add-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_add.c Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_fifo-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_fifo.c Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_pointers-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_pointers.c Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_quadran_fifo-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_quadran-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_quarter_fifo-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_quarter_fifo.c Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_quarter-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_quarter.c Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_struct-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile_struct.c Initial commit. 2023-10-17 14:19:03 +02:00
sandpile-100000.png Initial commit. 2023-10-17 14:19:03 +02:00
sandpile-video.c Initial commit. 2023-10-17 14:19:03 +02:00
sandpile.c Initial commit. 2023-10-17 14:19:03 +02:00

Searching for a fast Abelian Sandpile implementation

For context about the Abelian Sandpile Model see: https://en.wikipedia.org/wiki/Abelian_sandpile_model

I'm focusing only on the "flattening" step which I like to call "apply_gravity" in my code.

I'm focusing only in flattening a single huge pile of sand placed in the middle.

Here the performance I'm getting on an intel i9-9980HK:

sandpile_quarter.c

This is my fastest implemtation, it relies on the 8-fold symetry of flattening a centered pile. I in fact only rely on a 4-fold symmetry for simplicity, so it could be enchanced again.

Mean +- std dev: 208 ms +- 5 ms

sandpile_1d.c

This one does not rely on pointers of pointers to represent a 2d array. So no [x][y] access. Instead it represents the surface as an 1d line, in which, if the current cell is i:

  • the previous cell is at surface[i - 1]
  • the cell in the next row is at surface[i + width]
  • the cell in the previous row is at surface[i - width]
  • the next cell is at surface[i + 1]

Mean +- std dev: 731 ms +- 9 ms

sandpile.c

This is the "dumb" implementation.

Mean +- std dev: 750 ms +- 10 ms

sandpile_struct.c

This one is just to measure the cost of using a struct to store together the width and the values.

Mean +- std dev: 936 ms +- 16 ms

sandpile_quarter_fifo.c

This is a merge of the fifo implementation and the quarter one.

Mean +- std dev: 831 ms +- 14 ms

sandpile_pointers.c

This one stores, for each cells, 4 pointers to the west, south, north, and east cells so incrementing them is easy.

Mean +- std dev: 933 ms +- 27 ms

sandpile_add.c

This one starts with a small (1024 typically) power of two stack of sand grains, applies gravity on it, and multiply the resulting grid by two. This is done iteratively until the needed number of grains is reached.

The resulting grid is the same, but the performance are not better.

Mean +- std dev: 1.18 sec +- 0.03 sec

sandpile_fifo.c

This one is the "smart" one, instead of doing a full scan of the grid, a FIFO of points to fire is kept up to date each time a cell is firered.

Mean +- std dev: 2.81 sec +- 0.05 sec