PerlinNoise icon indicating copy to clipboard operation
PerlinNoise copied to clipboard

slow grad functions

Open SollyBunny opened this issue 1 year ago • 1 comments

Your grad functions use switch statements which are bad for branch prediction

Here are their alternatives (in c, because I converted this to c)


static const perlinfloat_t dot_grad3_gradients[8][2] = {
    { 1,  1},
    { 1,  0},
    { 1, -1},
    { 0, -1},
    {-1, -1},
    {-1,  0},
    {-1,  1},
    { 0,  1}
};
static inline perlinfloat_t dot_grad3(int hash, perlinfloat_t xf, perlinfloat_t yf) {
	// In 2D case, the gradient may be any of 8 direction vectors pointing to the
	// edges of a unit-square. The distance vector is the input offset (relative to
	// the smallest bound).
	int index = hash & 0x7;
	perlinfloat_t gx = dot_grad3_gradients[index][0];
	perlinfloat_t gy = dot_grad3_gradients[index][1];
	return gx * xf + gy * yf;
}

static const perlinfloat_t dot_grad4_gradients[16][3] = {
	{ 1.0,  1.0, 0.0}, {-1.0,  1.0, 0.0}, { 1.0, -1.0, 0.0}, {-1.0, -1.0, 0.0},
	{ 1.0,  0.0, 1.0}, {-1.0,  0.0, 1.0}, { 1.0,  0.0, -1.0}, {-1.0,  0.0, -1.0},
	{ 0.0,  1.0, 1.0}, { 0.0, -1.0, 1.0}, { 0.0,  1.0, -1.0}, { 0.0, -1.0, -1.0},
	{ 1.0,  1.0, 0.0}, {-1.0,  0.0, 1.0}, { 0.0,  1.0, -1.0}, { 0.0, -1.0, -1.0}
};
static inline perlinfloat_t dot_grad4(int hash, perlinfloat_t xf, perlinfloat_t yf, perlinfloat_t zf) {
	// In 3D case, the gradient may be any of 12 direction vectors pointing to the edges
	// of a unit-cube (rounded to 16 with duplications). The distance vector is the input
	// offset (relative to the smallest bound).
	const perlinfloat_t *g = dot_grad4_gradients[hash & 0xF];
	return g[0] * xf + g[1] * yf + g[2] * zf;
}

SollyBunny avatar Jun 28 '24 17:06 SollyBunny

Thank you for your suggestion! I'll test it when I have some time.

Reputeless avatar Jun 29 '24 16:06 Reputeless

wrong repo, oops!

SollyBunny avatar Aug 09 '24 12:08 SollyBunny