Я использую gcc-реализацию openmp, чтобы попытаться распараллелить программу. По сути, задача заключается в добавлении прагм omp для ускорения работы программы, которая находит дружных чисел .
Была дана оригинальная серийная программа (показанная ниже, за исключением 3 строк, которые я добавил с комментариями в конце). Мы должны сначала парализовать только внешний цикл, а затем только внутренний цикл. Внешний цикл был прост, и я приблизился к идеальному ускорению для данного числа процессоров. Что касается внутреннего цикла, я получаю гораздо худшую производительность, чем оригинальная последовательная программа. По сути, я пытаюсь сократить переменную суммы.
Глядя на использование процессора, я использую только ~ 30% на ядро. Что может быть причиной этого? Постоянно ли программа создает новые потоки каждый раз, когда сталкивается с предложением omp параллельно для предложения? Есть ли намного больше накладных расходов при создании барьера для сокращения? Или это может быть проблема доступа к памяти (например, кэш-памяти)? Из того, что я прочитал с большинством реализаций потоков openmp, повторно используются сверхурочные (например, в пуле), поэтому я не уверен, что первая проблема в том, что не так.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include <omp.h>
#define numThread 2
int main(int argc, char* argv[]) {
int ser[29], end, i, j, a, limit, als;
als = atoi(argv[1]);
limit = atoi(argv[2]);
for (i = 2; i < limit; i++) {
ser[0] = i;
for (a = 1; a <= als; a++) {
ser[a] = 1;
int prev = ser[a-1];
if ((prev > i) || (a == 1)) {
end = sqrt(prev);
int sum = 0;//added this
#pragma omp parallel for reduction(+:sum) num_threads(numThread)//added this
for (j = 2; j <= end; j++) {
if (prev % j == 0) {
sum += j;
sum += prev / j;
}
}
ser[a] = sum + 1;//added this
}
}
if (ser[als] == i) {
printf("%d", i);
for (j = 1; j < als; j++) {
printf(", %d", ser[j]);
}
printf("\n");
}
}
}