views:

97

answers:

2

I would like to map a thread_id. This in C/CUDA but it is more an algebraic problem that I am trying to solve.

So the mapping I am trying to achieve is along the lines:

  • Threads 0-15: read value array[0]
  • Threads 16-31: read value [3]
  • Threads 32-47: read value [0]
  • Threads 48-63: read value [3]
  • Threads 64-79: read value array[6]
  • Threads 80-95: read value array[9]
  • Threads 96-111: read value array[6]
  • Threads 112-127: read value array[9]

and so on..

Note this is a simplification of the mapping, in reality there are more than 128 threads but the sequence is as shown and threads would always map to a multiple of three.

What formula can I use that each thread can run to find out what array position it should look at?

I would like to use some kind of formula as I have in the following example and not an explicit map or any if-statements.

To illustrate how I have solved this for a different case which required a different mapping, i.e.:

  • Threads 0-31: read value array[0]
  • Threads 32-63: read value [3]

I used the code

rintf(float(tid)/96.0)*3

Thanks

+6  A: 

This will work in C:

3 * ((n>>4 & 1) + (n>>5 & ~1))

where n is the thread number.

I made the assumption here that the pattern continues beyond 128 as: 0,3,0,3,6,9,6,9,12,15,12,15,etc.

Edit:

This form, without bitwise operations, may be easier to understand:

6 * (n/64) + 3 * ((n/16) % 2)

It will give the same results. n is assumed to be an integer, so that division will round down.

interjay
Apologies, I did look at the posted answers and appreciate the answers. I am not sure how your solution is working.
zenna
I added a simpler version. Let me know if it needs clarification.
interjay
Tom
@Tom: It's the second part of the expression that makes it continue rather than repeat. I tested it and it works correctly.
interjay
My mistake, I'm an idiot! I actually have no idea what I was thinking.
Tom
A: 
int f(int thread_id)
{
    int tmp = thread_id % 64;
    int tmp2 = thread_id / 64;
    if (tmp =< 15 || (tmp >= 32 && tmp <= 47))  {
         return tmp2 * 6;
    } else {
         return tmp2 * 6 + 3;
    }
}
skwllsp