The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"падение производительности при включении OpenMP инструкций"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"падение производительности при включении OpenMP инструкций" 
Сообщение от jester Искать по авторуВ закладки(??) on 01-Дек-05, 16:54  (MSK)
проблема следующая. AIX 5.2 VisualAge c++ компилятор 6.2
написал простенький пример: создается меп из 10000 элементов, каждый элемент содержит вектор из 90000 элементов. потом это все разрушается. на этапе разрушения включаю omp parallel for. результат - падение производительности в 3-4 раза. причем не только на этапе разрушения, но и при создании. :-0 объясните кто-нить сей парадокс...
  Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Сообщения по теме [Сортировка по времени, UBB]

1. "падение производительности при включении OpenMP инструкций" 
Сообщение от horsh Искать по авторуВ закладки(??) on 02-Дек-05, 01:24  (MSK)
>проблема следующая. AIX 5.2 VisualAge c++ компилятор 6.2
>написал простенький пример: создается меп из 10000 элементов, каждый элемент содержит вектор
>из 90000 элементов. потом это все разрушается. на этапе разрушения включаю
>omp parallel for. результат - падение производительности в 3-4 раза. причем
>не только на этапе разрушения, но и при создании. :-0 объясните
>кто-нить сей парадокс...

Чтобы дать осмысленный ответ нужно знать подробности:

Сколько процессоров? Каких? Какого размера у них кэши?

Сколько openmp порождает потоков?

Да и исходник бы посмотреть, если не жалко.

Например, если процессор один,
потоков сто, то замедление вполне вероятно.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "падение производительности при включении OpenMP инструкций" 
Сообщение от jester Искать по авторуВ закладки(ok) on 02-Дек-05, 12:02  (MSK)
>
>Чтобы дать осмысленный ответ нужно знать подробности:
>
>Сколько процессоров? Каких? Какого размера у них кэши?
>
>Сколько openmp порождает потоков?
>
>Да и исходник бы посмотреть, если не жалко.
>
>Например, если процессор один,
>потоков сто, то замедление вполне вероятно.


да запросто. пример тестовый без авторских прав :)

struct VectorElement {

   float f;

};

struct MapElement {

   int i;
   std::vector<VectorElement*> v;

};

int main(int argc, char *argv[]) {

   std::map<int, MapElement> m;
   VectorElement        *ve;
   MapElement           me;

   struct tms           buf = {0, 0, 0, 0};
   times(&buf);
   std::cout << pthread_self()
        << "   Before  init : u ="
<< buf.tms_utime / sysconf(_SC_CLK_TCK)
<< "; s =" << buf.tms_stime / sysconf(_SC_CLK_TCK)
<< std::endl;

   for (int i = 0; i < 1000; ++i) {
      for (int j = 0; j < 90000; ++j) {
         ve = new VectorElement;
         ve->f = j;
         me.v.push_back(ve);
      }

      me.i = i;
      m.insert(std::make_pair<int, MapElement>(i, me));
      me.v.clear();
   }

   times(&buf);
   std::cout << pthread_self()
        << "   After  init : u ="
<< buf.tms_utime / sysconf(_SC_CLK_TCK)
<< "; s ="
<< buf.tms_stime / sysconf(_SC_CLK_TCK)
<< std::endl;

   std::vector<VectorElement*> *p;
   int                         j, i;
   std::vector<std::map<int, MapElement>::iterator> mis;
   for (std::map<int, MapElement>::iterator mIt = m.begin();
        mIt != m.end(); ++mIt) {
      mis.push_back(mIt);
   }

   times(&buf);
   std::cout << pthread_self()
        << "   After  preparing for destroy : u ="
<< buf.tms_utime / sysconf(_SC_CLK_TCK)
<< "; s ="
<< buf.tms_stime / sysconf(_SC_CLK_TCK)
<< std::endl;

   #pragma omp parallel private(i, p, j)
   {
      #pragma omp for schedule(dynamic)
      for (i = 0; i < mis.size(); ++i) {
         p = &mis[i]->second.v;

         for (j = 0; j < p->size(); ++j) {
            delete (*p)[j];
         }

         p->clear();
      }
   }

   times(&buf);
   std::cout << pthread_self()
        << "   After  destroy : u ="
<< buf.tms_utime / sysconf(_SC_CLK_TCK)
<< "; s ="
<< buf.tms_stime / sysconf(_SC_CLK_TCK)
<< std::endl;

   m.clear();

}

процессоров 2 PowerPC_Power4, 6 гиг озу, скоко кеша не знаю
потоков 2. aix дефолтом выставляет. определял и через OMP_NUM_THREADS.

статистика такова: без прагмы удаление массива за 44 сек, с включенным омп - 150-160сек
пока стояла дирректива parallel for - тормозило даже создание массива (20 сек без омп против 45-50 с включ омп)

заранее спасибо огромное

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "падение производительности при включении OpenMP инструкций" 
Сообщение от horsh Искать по авторуВ закладки(ok) on 02-Дек-05, 21:46  (MSK)
>>
>>Чтобы дать осмысленный ответ нужно знать подробности:
>
>да запросто. пример тестовый без авторских прав :)
>
>
>   #pragma omp parallel private(i, p, j)
>   {
>      #pragma omp for schedule(dynamic)
>      for (i = 0; i < mis.size(); ++i) {
>         p = &mis[i]->second.v;
>
>         for (j = 0; j < p->size(); ++j) {
>            delete (*p)[j];
>         }
>
>         p->clear();
>      }
>   }
>
>процессоров 2 PowerPC_Power4, 6 гиг озу, скоко кеша не знаю
>потоков 2. aix дефолтом выставляет. определял и через OMP_NUM_THREADS.
>

Ага. Ну вот теперь все гораздо понятней.

(У меня, правда, Solaris, но все выглядит очень похоже)

первым делом запускаем это дело под профилировщиком.
В моем случае это Performance Analyzer из Sun Studio.
Два раза: для OMP_NUM_THREADS=1 и OMP_NUM_THREADS=2

видим почти одинаковые картинки, но для двух потоков
лишнее время тратится на функции из malloc.h, и libc-шную синхронизацию.

Вспоминаем, что обычный malloc с друзьями
"mt safe, not mt hot". Проверяем на чем-нибудь попроще
чем изначальный пример на C++

Пишу программу с openmp которая много раз маллочит и реаллочит.
Убеждаюсь, что чем больше потоков тем хуже.

        #pragma omp parallel for
        for(i=0; i<N; i++) {
                p[i] = malloc(1);
                for (j=0; j<1000; j++) {
                        p[i] = realloc(p[i], 1);
                }
        }


-bash-3.00$ cc -xO4 t.c -xopenmp
-bash-3.00$ export  OMP_NUM_THREADS=1; time ./a.out

real    0m7.469s
user    0m7.462s
sys     0m0.005s
-bash-3.00$ export  OMP_NUM_THREADS=2; time ./a.out

real    0m29.631s
user    0m55.658s
sys     0m1.110s


Что же делать? Нужен другой аллокатор!
На Солярисе есть libumem. Попробуем:

-bash-3.00$ cc -xO4 t.c -xopenmp -lumem
-bash-3.00$ export  OMP_NUM_THREADS=1; time ./a.out

real    0m5.768s
user    0m5.734s
sys     0m0.005s
-bash-3.00$ export  OMP_NUM_THREADS=2; time ./a.out

real    0m2.756s
user    0m5.761s
sys     0m0.006s

Полегчало. Теперь к исходному примеру:

-bash-3.00$CC -xO4 t.cc -xopenmp -lumem
-bash-3.00$ export  OMP_NUM_THREADS=1; time ./a.out
1   Before  init : u =0; s =0

1   After  init : u =27; s =1
1   After  preparing for destroy : u =27; s =1
1   After  destroy : u =47; s =2

real    0m50.877s
user    0m47.380s
sys     0m2.242s
-bash-3.00$ export  OMP_NUM_THREADS=2; time ./a.out
1   Before  init : u =0; s =0
1   After  init : u =27; s =1
1   After  preparing for destroy : u =27; s =1
1   After  destroy : u =65; s =2

real    0m49.948s
user    1m5.873s
sys     0m2.114s

Ну вот, основной кусок починился.

Дальше сам.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх


Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру