Closed SollyBunny closed 1 month ago
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; }
Thank you for your suggestion! I'll test it when I have some time.
wrong repo, oops!
Your grad functions use switch statements which are bad for branch prediction
Here are their alternatives (in c, because I converted this to c)