Я в настоящее время использую следующую функцию Reduction просуммировать все элементы в массиве с CUDA:CUDA Сокращение на разделяемой памяти с несколькими массивами
__global__ void reduceSum(int *input, int *input2, int *input3, int *outdata, int size){
extern __shared__ int sdata[];
unsigned int tID = threadIdx.x;
unsigned int i = tID + blockIdx.x * (blockDim.x * 2);
sdata[tID] = input[i] + input[i + blockDim.x];
__syncthreads();
for (unsigned int stride = blockDim.x/2; stride > 32; stride >>= 1)
{
if (tID < stride)
{
sdata[tID] += sdata[tID + stride];
}
__syncthreads();
}
if (tID < 32){ warpReduce(sdata, tID); }
if (tID == 0)
{
outdata[blockIdx.x] = sdata[0];
}
}
Однако, как вы можете видеть из параметров функции я бы чтобы иметь возможность суммировать три отдельных массива внутри одной функции сокращения. Теперь, очевидно, простой способ сделать это - это запустить Kernel три раза и каждый раз передавать разные массивы, и это будет нормально работать. Я просто пишу это как тестовое ядро только сейчас, но реальное ядро закончит тем, что возьмет массив структур, и мне нужно будет выполнить добавление для всех значений X, Y и Z каждой структуры, поэтому Мне нужно суммировать их все в одном ядре.
Я initalised и выделяется память для всех трех массивов
int test[1000];
std::fill_n(test, 1000, 1);
int *d_test;
int test2[1000];
std::fill_n(test2, 1000, 2);
int *d_test2;
int test3[1000];
std::fill_n(test3, 1000, 3);
int *d_test3;
cudaMalloc((void**)&d_test, 1000 * sizeof(int));
cudaMalloc((void**)&d_test2, 1000 * sizeof(int));
cudaMalloc((void**)&d_test3, 1000 * sizeof(int));
Я не уверен, что сетки и блоков измерения следует использовать для такого рода ядро, и я не совсем уверен, как изменить цикл сокращения в разместить данные, как я хочу, то есть выходного массива:
Block 1 Result|Block 2 Result|Block 3 Result|Block 4 Result|Block 5 Result|Block 6 Result|
Test Array 1 Sums Test Array 2 Sums Test Array 3 Sums
Я надеюсь, что имеет смысл. Или есть лучший способ иметь только одну функцию сокращения, но иметь возможность вернуть суммирование Struct.X, Struct.Y или struct.Z?
Вот структура:
template <typename T>
struct planet {
T x, y, z;
T vx, vy, vz;
T mass;
};
Мне нужно сложить все VX и хранить его, все VY и хранить его и все VZ и хранить его.
Почему бы не указать фактическое определение массива структур, которые вы хотели бы суммировать? Это просто: 'struct my_struct {int x, y, z;} data [1000];'?Причина, по которой это важно, заключается в том, что такая операция сокращения будет ограничена полосой пропускания памяти. Поэтому для обеспечения максимальной производительности важно понимать данные в памяти, а также схему доступа. Хорошим решением будет оптимизация шаблона доступа к памяти для оптимизации использования доступной пропускной способности памяти. –
Извините, вы правы, я обновил основной пост с помощью определения структуры. –