Мне нужен совет о том, как действовать и использовать вычислительную мощность устройства CUDA для численного интегрирования функции. Ниже приведена некоторая информация о моем устройстве (не имеет значения)
Аппаратное обеспечение
Geforce GTX470; Compute Capability 2.0
описание проблемы
У меня есть функция вроде
g(x) = x * f(x, a, b, c)
Что мне нужно интегрировать как указано уравнение
Теперь я уже написал функцию интегрирования, которая просто берет g(x), разбивает интервал на N подинтервалов, вычисляет результат для отдельного подинтервала, а затем я суммирую его на процессоре. Для завершения я привожу ниже пример кода.
__device__ float function(float x, float a, float b, float c) {
// do some complex calculation
return result;
}
__global__ void kernel(float *d_arr, float a, float b, float c, int N) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
float x = (float)idx / (float)N;
if (idx < N) {
d_arr[idx] = x * function(x, a, b, c);
}
}
Приведенный выше код предназначен только для демонстрационных целей, на самом деле я использую метод Ромберга для интеграции моего g(x), но идея та же. Моя настоящая проблема возникает из-за того, что у меня нет только одного набора значений (a, b, c), у меня есть несколько значений этого набора.
У меня есть 2D-массив в памяти устройства, точно (3, 1024) 3 строки, 1024 столбца. Каждый столбец представляет отдельный набор, для которого необходимо выполнить функцию интегрирования.
Проблема возникает, когда я должен решить, буду ли я выполнять блок потоков, такой как 1024, имея в виду, что один поток эквивалентен одной функции интеграции. В этом случае функция, которую я написал выше, бесполезна. Поскольку я хочу выполнить параллельную интеграцию для всех наборов значений, мне нужно написать функцию интеграции, которая может выполнять интеграцию последовательно. Например:
__global__ void kernel(float *d_arr, float a, float b, float c, int N) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
float sum = 0;
for (int i = 0; i < N; i++) {
float x = (float)i / (float) N;
sum += x * function(x, a, b, c);
}
d_arr[idx] = sum;
}
Итак, вы понимаете мою точку зрения? Вариант А кажется лучше, но я не могу его использовать, потому что я не знаю, как я могу сделать несколько интегралов, а затем распределить каждый интеграл по N потокам.
Как бы вы это сделали? Можете ли вы предложить мне, как я могу добиться как нескольких интегралов, так и того, что каждый интеграл может быть распределен по N потокам? Есть ли лучший способ сделать это.
С нетерпением жду вашего совета.