2012-01-31 5 views
3

Я использую gcc для реализации openmp, чтобы попытаться распараллелить программу. В основном назначение заключается в том, чтобы добавить omp pragmas для получения ускорения в программе, которая находит amicable numbers.gcc openmp thread reuse

Первоначальная серийная программа была предоставлена ​​(показано ниже, за исключением трех строк, которые я добавил с комментариями в конце). Сначала мы должны сначала парализовать внешний контур, а только внутренний цикл. Внешний контур был легким, и я приближаюсь к идеальному ускорению для определенного количества процессоров. Для внутреннего цикла я получаю намного худшую производительность, чем исходная серийная программа. В основном то, что я пытаюсь сделать, - это сокращение от переменной суммы.

Глядя на использование процессора, я использую только 30% на ядро. Что может быть причиной этого? Является ли программа постоянным образом создавать новые потоки каждый раз, когда она попадает в omp parallel for clause? Есть ли еще больше накладных расходов, чтобы сделать барьер для сокращения? Или это может быть проблема с доступом к памяти (например, сбой кэша)? Из того, что я читал в большинстве реализаций потоков 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"); 
     } 
    } 
} 
+0

IS это C++.?! – jjj

+0

@jjj выглядит как C мне. Почему вы думаете, что это C++? – sehe

+0

Вы добавили -fopenmp в команду компиляции? – batbaatar

ответ

7

OpenMP thread teams инстанцируются при входе в параллельную секцию. Это означает, что создание потока повторяется каждый раз, когда начинается внутренний цикл.

Чтобы включить повторное использование потоков, использовать большую параллельную секцию (для контроля времени жизни команды) и специфический контролировать параллельности для внешних/внутренних циклов, например, так:

Времени выполнения test.exe 1 1000000 пошла вниз от 43s до 22s с помощью исправления (и количества потоков отражает numThreads определенного значений +-

PS Возможно констатирует очевидные, это не будет казаться, что распараллеливание внутреннего цикла является мерой производительности звука. Но вероятно, весь смысл этого упражнения, и я не критиковать вопрос для этого.

#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]); 
#pragma omp parallel num_threads(numThread) 
    { 
#pragma omp single 
     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) //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"); 
      } 
     } 
    } 
} 
+0

Вы являетесь профессионалом. Время для чтения в группах нитей. –

+0

@JamesCotter: радуйтесь и продолжайте! – sehe

+0

Hmm wait a sec ... запуск серийной программы завершается за 3 секунды, в то время как резьба заканчивается примерно на 15 секунд для аргументов 2 1000000. –

Смежные вопросы