Отображение номера потока в (не последовательную) позицию в массиве - PullRequest
1 голос
/ 11 февраля 2010

Я хотел бы отобразить thread_id. Это в C / CUDA, но это скорее алгебраическая проблема, которую я пытаюсь решить.

Итак, карта, которую я пытаюсь достичь, выглядит следующим образом:

  • Потоки 0-15: чтение массива значений [0]
  • Темы 16-31: чтение значения [3]
  • Темы 32-47: чтение значения [0]
  • Темы 48-63: чтение значения [3]
  • Потоки 64-79: чтение массива значений [6]
  • Потоки 80-95: чтение массива значений [9]
  • Потоки 96-111: чтение массива значений [6]
  • Потоки 112-127: чтение массива значений [9]

и т. Д.

Обратите внимание, что это упрощение отображения, в действительности существует более 128 потоков, но последовательность такая, как показано, и потоки всегда будут отображаться кратно трем.

Какую формулу я могу использовать, чтобы каждый поток мог запускать, чтобы выяснить, какую позицию массива он должен смотреть?

Я хотел бы использовать какую-то формулу, как в следующем примере, а не явную карту или какие-либо операторы if.

Чтобы проиллюстрировать, как я решил эту проблему для другого случая, для которого требовалось другое отображение, т. Е .:

  • Потоки 0-31: чтение массива значений [0]
  • Темы 32-63: чтение значения [3]

Я использовал код

rintf(float(tid)/96.0)*3

Ответы [ 2 ]

6 голосов
/ 11 февраля 2010

Это будет работать в C:

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

где n - номер потока.

Я сделал здесь предположение, что паттерн продолжается после 128 как: 0,3,0,3,6,9,6,9,12,15,12,15 и т. Д.

Edit:

Эта форма, без побитовых операций, может быть легче для понимания:

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

Это даст те же результаты. n предполагается как целое число, поэтому деление округляется вниз.

0 голосов
/ 11 февраля 2010
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;
    }
}
...