Выполнение одного и того же цикла for во многих потоках GPU с использованием OpenCL

Мне нужно вычесть 2D-массив, Dот многих других двухмерных массивов. Я линеаризовал (сплющил) все массивы: D является массивом из 25 элементов, и imges является одномерным массивом, в котором 4 25-элементных массива были объединены. Значение: если я хочу вычесть D из 4 массивов 5x5 я просто превращаю каждый из этих массивов 5x5 в один массив из 25 элементов, а затем добавляю 4 массива. Это то что imgs в этом примере это будет массив из 100 элементов. Я считаю, что правильно фиксирую это в своем ядре по индексу.

Единственный способ прийти к вычитанию - это запустить for цикл, так что каждый элемент из D будет вычтено из массива в соответствующем потоке. Моя идея состояла в том, что это будет работать следующим образом:

  1. Каждый поток получит D вычитаемый массив и один из массивов, из которого D должен быть вычтен из (в моем примере, 1/4 imges)

  2. Я бы перебрал элементы обоих массивов с помощью цикла for, чтобы сделать элемент вычитания элементом

Тем не менее, он не работает, как ожидалось: кажется, только последнее или первое значение D выбирается и затем вычитается из всех элементов других массивов.

Я думал, что у меня есть представление о том, как индексирование и многопоточность работают на GPU, но теперь я не уверен, так как это бросало мне вызов некоторое время. Ядро ниже.

Есть ли лучший способ сделать это, кроме как для цикла? Заранее большое спасибо.

__kernel void reduce(__global float* D, __global float* imges, __global float* res)
{
    const int x = (int)get_global_id(0);
    const int y = (int)get_global_id(1);
    const int z = (int)get_global_id(2);

    int im_i = imges[x+25]; //Images are 5x5 meaning a 25-size array

   for(int j = 0; j < 25; j++){
       res[x+25] = im_i - D[j];
   }
}

Изменить: я не хочу распараллеливать for сам цикл, так как массивы, вероятно, станут больше, и я не хочу сталкиваться с проблемами из-за накладных расходов.

1 ответ

Решение

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

__kernel void reduce(__global float* D, __global float* imges, __global float* res)
{
  const int x = (int)get_global_id(0);

  for(int j = 0; j < 25; j++){
    res[x*25 + j] = imges[x*25 + j] - D[j];
  }
}

Это ядро ​​вычтет jй элемент D от jэлемент 25-элементного массива каждого рабочего элемента в imges,

Другие вопросы по тегам