static uint64_t deinterleave(uint64_t x) {
x = x & 0x5555555555555555;
x = (x | (x >> 1)) & 0x3333333333333333;
x = (x | (x >> 2)) & 0x0f0f0f0f0f0f0f0f;
x = (x | (x >> 4)) & 0x00ff00ff00ff00ff;
x = (x | (x >> 8)) & 0x0000ffff0000ffff;
x = (x | (x >> 16)) & 0x00000000ffffffff;
return x;
}
static void get_gray_xy(uint64_t n, uint64_t *x, uint64_t *y) {
uint64_t gray = n ^ (n >> 1);
*x = deinterleave(gray);
*y = deinterleave(gray >> 1);
}
I don't think the gray code solution can work well for sets of different sizes because the area of indexes that you go through grows as a square.But it does work for different number of dimensions or different number of nested loops. For 3 dimensions each coordinate is constructed from every 3rd bit instead of 2nd.
So if you have index 14, then gray code is 9 (1001) which means in two dimensions x=1,y=2 and in three dimensions, x=3,y=0,z=0.
I would like to generalise it for sets of different sizes. Maybe it's something different to a gray codes which you taught me today, it feels that it should be simple.
Maybe someone kind can step in and help me or I can ask it on Stackoverflow.
I need to think it through.
At one point in time I was reading a section on Intel's website of cache optimisation using a tool that shows you the cache behaviour of the CPU and column or row major iteration it had a GUI. I found it very interesting but I cannot seem to find it at this time. I did find some medium article of Cachediff.
Wikipedia says graycodes can be found by num ^ (num >> 1)
This produces the sequence: