На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: 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: а с опенмп еще надо постоянно анализировать потоки в потоках :)

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

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


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0817 ]   [ 17 queries used ]   [ Generated: 29.03.24, 01:27 GMT ]