2016-05-05 3 views
2

В настоящее время я пишу программу, которая выделяет 2D-блоки большого 2D-массива и помещает их в меньший 2D-массив. Массивы фактически сохраняются как массивы 1D, но я предполагаю, что они представляют собой 2D-массивы, которые выпрямляются. Прямо сейчас для циклов убедитесь, что я вынимаю Nx, Ny элементов большой петли, прежде чем переходить к новой части большого массива.Unwrapping 3 C++ loops in cuda

Я не могу найти способ сделать это более эффективно в ядре CUDA. Я мог бы сделать решение, если бы имел только массивы одинакового размера. Но с новым местоположением после каждого элемента Nx * Ny я запутался.

Ниже приведены три петли, которые заставляют все это происходить. posx и posy содержат координаты, которые должны быть вычтены стартовыми позициями.

for (int i = 0; i < loadsize; i++) 
    { 
     for (int k = 0; k < Searchsizey; k++) 
     { 
      for (int l = 0; l < Searchsizex; l++) 
      { 
       img[count] = ImgInt[posx[i] - ImgStartx + (posy[i] - ImgStarty) * sizex + sizex*k + l]; 
       count++; 
      } 
     } 
    } 

Проблема в том, что две внутренние петли работают максимально до Searchsizex и Searchseyey. Если я должен реализовать это в ядре с использованием l и k в качестве индексации из потоков, они станут больше, чем Searchsizex и Searchsizey.

Я думал о создании ядра CUDA, которое выполняет итерацию корыта i, но он действительно кажется очень эффективным для этого. Ниже я расскажу о том, как включить ядро, но мне это не очень нравится. Его единственный вид «полупараллельный».

Упование вы имеете некоторые предложения для как сделать эту параллель, спасибо!

int l = blockIdx.x*blockDim.x + threadIdx.x; 
int k = blockIdx.y*blockDim.y + threadIdx.y; 
     for (int i = 0; i < loadsize; i++){ 
      img[l + k*sizex + (i*sizex*sizey)] = ImgInt[posx[i] - ImgStartx + (posy[i] - ImgStarty) * sizex + sizex*k + l];   
     } 
+2

В зависимости от размеров вашего ввода и величины posx и posy могут подойти различные подходы. Не могли бы вы предоставить приблизительные показатели для них? Также тип данных img? –

+0

posx и posy могут варьироваться от 0 до 1000 и там размер loadzie может составлять сотни. Img - это float – LukaK

+1

Чтобы получить максимальную производительность, вы хотите использовать float4 как записи и в зависимости от целевого оборудования, используйте текстуру или поверхность для ImgInt. В остальном ваш подход к параллелизму кажется очень разумным. –

ответ

1

Так что, я думаю, поскольку больше не было ответов на эту тему, я буду использовать комментарий Флоренса в качестве ответа.

Запись должна иметь тип float4, и в зависимости от целевого оборудования для ImgInt следует использовать текстуру или поверхностный тип данных.

Помимо этого подход параллелизма кажется очень разумным.