CUDA: метод разделения * огромные * проблемы? - PullRequest
2 голосов
/ 19 апреля 2011

Вся эта жаворонка CUDA тает в своей силе, но что-то, о чем я удивляюсь, это жесткие ограничения на размеры 1d блока / сетки (обычно 512/65535 соответственно).с проблемами, которые намного больше по своим масштабам (порядка миллиардов), существует ли автоматизированный программный способ эффективной установки «очереди» через ядро, или это случай ручной нарезки и нарезки кубиками?

Как все справляются с проблемой разделения?

Ответы [ 2 ]

1 голос
/ 21 апреля 2011

Существует 2 основных способа разделения данных, чтобы вы могли работать с ними с помощью CUDA:

  1. Разбить данные на непрерывные куски , чтобы каждый поток работална один кусок.
  2. Каждый поток откусывает один элемент данных.Когда все потоки завершены, они сдвигаются на numberOfThreads и повторяются снова.

Я объяснил эти методы на простых примерах здесь .Метод 2 обычно проще в написании кода и работе с большинством задач.

1 голос
/ 19 апреля 2011

Если одномерные сетки слишком малы, просто используйте вместо этого двумерные (или трехмерные в Fermi с CUDA 4.0) сетки. Размерность в сетке и блочных макетах действительно только для удобства - она ​​делает пространство выполнения похожим на обычные пространства ввода параллельных данных, с которыми работают программисты (матрицы, сетки, воксели и т. Д.). Но это лишь очень малая абстракция от базовой простой линейной схемы нумерации, которая может обрабатывать более 10 ^ 12 уникальных идентификаторов потоков за один запуск ядра.

В сетках упорядочение является основным по столбцу, поэтому, если раньше у вас была проблема с 1D сеткой, «уникальный, 1D индекс потока» был рассчитан как:

unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;

, теоретический верхний предел которого составляет 512 * 65535 = 33553920 уникальных потоков. Эквивалентная двумерная сеточная задача - это лишь простое расширение одномерного случая

size_t tidx = threadIdx.x + blockIdx.x * blockDim.x;
size_t tid = tidx + blockIdx.y * blockDim.x * GridDim.x;

с теоретическим верхним пределом 512 * 65535 * 65535 = 2198956147200 уникальных потоков. Fermi позволит вам добавить третье измерение в сетку, также с максимальным размером 65535, что дает до 10 ^ 17 потоков в одной сетке выполнения. Что довольно много.

...