На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: JoeUser, Qraizer, Hsilgos
  
> Распараллеливание с помощью openmp
Здравствуйте, вообщем пытаюсь использовать Openmp, чтобы распараллелить задачу вычисления экспоненты с помощью ряда Тейлора. Программа работает, но при сравнении времени выполнения последовательного кода и с Openmp, нет прироста скорости, а даже наоборот выполняется дольше с Openmp. В чем может быть причина, не могли бы вы помочь?
ExpandedWrap disabled
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <omp.h>
    int fact(int c);
    double taylor(double x, int n);
     
    int main(int argc, char *argv[]) {
      double x=0;
      int n=0;
      int n_max = 32;
      if (argc != 3) {
      printf("Input three parametrs!\n");
      return 1;
    }
      sscanf(argv[1], "%lf", &x);
      sscanf(argv[2], "%d", &n);
     
     if((n>n_max)||(n<0)) {
     printf("Invalid parameter n, enter n from 0..10\n");
     return 1;
     }
        
     int i;
     double sum=0 ;
     double t = omp_get_wtime();
     
      #pragma omp parallel for private(i) reduction(+: sum)
       for (i=1; i<=n; i++) {
          double taylor = pow(x,i)/fact(i);
          sum+=taylor;
      }
      
      double diff = omp_get_wtime() - t;
      printf("e^x = %lf\n Time: \t %lf\n", ++sum, diff);
      return 0;
    }
     
    int fact(int c) {
       int fact=1;
       int i;
       for (i = 1; i <= c; i++ ) {
          fact *=i;
       }
       return fact;
    }

./taylor 1 32
e^x = 2.718282
Time: 0.000126 - время выполнения с openmp

/staylor 1 32
e^x = 2.718282
Time: 0.000020 - время выполнения последовательного кода
Накладные на создание потоков велики. На 32-ух итерациях они не окупятся.
Одни с годами умнеют, другие становятся старше.
Слишком крохотные времена для функций. Попробуйте искусственно удлинить fact(), чтобы проверить действие распараллеливания. Можно прибавлять 2, а вычитать длиннющий ряд 1 + 1/2 + 1/4 + ... или что-то ещё такое.
Топорнейшим образом переписал вот так:
ExpandedWrap disabled
     double t;
     #pragma omp parallel private(i) reduction(+: sum)
     {
       for (i=1; i<=n; i++) {
          double taylor = pow(x,i)/fact(i);
          sum+=taylor;
      }
     sum = 0;
     t = omp_get_wtime();
       for (i=1; i<=n; i++) {
          double taylor = pow(x,i)/fact(i);
          sum+=taylor;
      }
     }
чтобы время создания не учитывалось, получил:
ExpandedWrap disabled
    e^x = 7.873127
     Time:   0.000012
    ...
    e^x = 7.873127
     Time:   0.000005
Но всё равно, 32 итерации – это крайне мало для накопления статистики. На отклонение будут влиять малейшие чихи ОС, включая асинхронные прерывания от сетевухи.
Одни с годами умнеют, другие становятся старше.
Qraizer, так всё ж "наоборот"! Не в 32 итерациях суть, а в мощности каждой из них. Если их хоть 8, или 3, и каждая будет работать по часу, то и выигрыш будет в разы! А если их хоть миллион, но каждая длится миллисекунды, то перещёлкивание потоков всё (выигрыш) и съест. Или как?.. :whistle:
Можно и так сказать. Только алгоритм на секунды не перепишешь, а итераций можно добавить.
Одни с годами умнеют, другие становятся старше.
если хочется выжать максимум из железа, то использование опенмп - плохая затея. только ручками и только с глубоким пониманием сабжа. на малых затратах итерации делить на потоки - организация потока, кэш, ух.... :facepalm: а с опенмп еще надо постоянно анализировать потоки в потоках :)
Сообщение отредактировано: _lcf_ -
Цитата _lcf_ @
если хочется выжать максимум из железа, то использование опенмп - плохая затея. только ручками и только с глубоким пониманием сабжа. на малых затратах итерации делить на потоки - организация потока, кэш, ух.... :facepalm: а с опенмп еще надо постоянно анализировать потоки в потоках :)

В каждом предложении не хватает завершения мысли в виде "потому что ..."
Мои программные ништякиhttp://majestio.info
а что там завершать? опенмп топорнейший инструмент, который тупо делит указанные части кода на потоки, нисколько не анализируя и не оптимизируя затраченное время и нагрузку процов. банальное гетнампроц и крэйттрид делает по сути то же самое :-? я бы сказал это инструмент для начинающих/ленивых :)
Цитата _lcf_ @
нисколько не анализируя и не оптимизируя затраченное время и нагрузку процов

А смысл у операционной системы забирать ее функции? Планирование загрузки процов - это же прерогатива ОС, не? Конечно можно насильно вязать нити к ядрам, но что это даст в профите? Я понимаю, если в пуле создаваемых нитей нагрузка (по времени) распределена неравномерно, тогда да. А если равномерно?
Мои программные ништякиhttp://majestio.info
1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
0 пользователей:


Рейтинг@Mail.ru
[ Script Execution time: 0,1074 ]   [ 20 queries used ]   [ Generated: 22.11.17, 23:53 GMT ]