CUDA: потоковая передача одной и той же ячейки памяти всем потокам

#cuda #broadcast

#cuda #трансляция

Вопрос:

Вот моя проблема: у меня довольно большой набор двойников (это массив из 77.500 двойников), который должен храниться где-то в cuda. Теперь мне нужен большой набор потоков, чтобы последовательно выполнять кучу операций с этим массивом. Каждый поток должен будет считывать ОДИН и ТОТ ЖЕ элемент этого массива, выполнять задачи, сохранять результаты в общей памяти и считывать следующий элемент массива. Обратите внимание, что каждый поток одновременно должен будет считывать (просто считывать) из одной и той же ячейки памяти. Итак, мне интересно: есть ли какой-нибудь способ транслировать один и тот же double во все потоки только с одним чтением памяти? Многократное чтение было бы совершенно бесполезным… Есть идеи??

Ответ №1:

Это обычная оптимизация. Идея состоит в том, чтобы заставить каждый поток взаимодействовать со своими соседями по блоку для чтения данных:

 // choose some reasonable block size
const unsigned int block_size = 256;

__global__ void kernel(double *ptr)
{
  __shared__ double window[block_size];

  // cooperate with my block to load block_size elements
  window[threadIdx.x] = ptr[threadIdx.x];

  // wait until the window is full
  __syncthreads();

  // operate on the data
  ...
}
 

Вы можете итеративно «перемещать» окно по элементам массива block_size (или, может быть, на несколько целых чисел больше) за раз, чтобы использовать все это целиком. Тот же метод применяется, когда вы хотите сохранить данные обратно синхронизированным образом.

Комментарии:

1. Также: трансляция из общей памяти (т. Е. Когда Все потоки в блоке считывают одну и ту же ячейку памяти) — это быстрый случай. В реализациях CUDA для задач с N-телом используется broadcast в сочетании с идиомой, описанной здесь Джаредом .