PARALLEL.RU

Дискуссионный клуб по параллельным вычислениям
Текущее время: 13 дек 17 0:35

Часовой пояс: UTC + 4 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
 Заголовок сообщения: gcc + OpenMP
СообщениеДобавлено: 4 мар 10 17:00 
Не в сети

Зарегистрирован: 28 май 07 12:10
Сообщения: 47
Откуда: ИПС РАН
Имею простейшую программу перемножения матриц, распараллеленную средствами OpenMP:

Код:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <malloc.h>

int main (int argc, char *argv[])
{
  int i,j,k;
  float *a,*b,*c;
  struct timeval timev1,timev2;
  float time_seconds;

  int N = atoi ( argv [ 1 ] );
  int P = atoi ( argv [ 2 ] );
  printf ( "N=%d   P=%d\n", N, P );

  a = (float*) malloc(N*N*sizeof(float));
  b = (float*) malloc(N*N*sizeof(float));
  c = (float*) malloc(N*N*sizeof(float));

  for(i=0;i<N*N;i++) {
   a[i]=0.1;
   b[i]=0.2;
   c[i]=0.0;
  }

  omp_set_num_threads(P);

  gettimeofday(&timev1,NULL);

  #pragma omp parallel for
  for (i=0; i<N; i++)
   for ( j = 0; j < N; j++)
    for (k=0; k<N; k++)     
     c[i*N+j]+=a[i*N+k]*b[k*N+j];

  gettimeofday(&timev2,NULL);
  time_seconds=timev2.tv_sec-timev1.tv_sec+0.000001*(timev2.tv_usec-timev1.tv_usec);

  printf("Computation time = %.4f\n",time_seconds);

  printf ( "c[0,0]=%f\n", c[0] );

  free(a);
  free(b);
  free(c);
}


Траслирую с помощью gcc ( v.4.1.2) и тестирую на 1-4 процессорах:

Код:
bash-3.2$ gcc -O3 -fopenmp -o mm_openmp mm_openmp.c

bash-3.2$ ./mm_openmp 1024 1
N=1024   P=1
Computation time = 7.9787
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 2
N=1024   P=2
Computation time = 4.4790
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 3
N=1024   P=3
Computation time = 2.9087
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 4
N=1024   P=4
Computation time = 2.3406
c[0,0]=20.480278


Замечаем, что результат вычислений (в частности, значение элемента c[0,0] ) одинаков, что и ожидаемо.

Теперь меняю порядок внутренних циклов в базовой части программы, что математически корректно:

Код:
#pragma omp parallel for
  for (i=0; i<N; i++)
   for (k=0; k<N; k++)
    for (j=0; j<N; j++)
     c[i*N+j]+=a[i*N+k]*b[k*N+j];


и снова тестирую. Получаю неправильные результаты вычисления при распараллеливании:

Код:
bash-3.2$ gcc -O3 -fopenmp -o mm_openmp mm_openmp.c

bash-3.2$ ./mm_openmp 1024 1
N=1024   P=1
Computation time = 2.3715
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 2
N=1024   P=2
Computation time = 1.5620
c[0,0]=20.600281
bash-3.2$ ./mm_openmp 1024 3
N=1024   P=3
Computation time = 0.9021
c[0,0]=20.180271
bash-3.2$ ./mm_openmp 1024 4
N=1024   P=4
Computation time = 0.6133
c[0,0]=8.039994


С другой стороны, при использовании icc всё работает корректно в обоих случаях:

а) без перестановки

Код:
bash-3.2$ icc -O3 -openmp -o mm_openmp mm_openmp.c
mm_openmp.c(34): (col. 3) remark: OpenMP DEFINED LOOP WAS PARALLELIZED.
mm_openmp.c(24): (col. 3) remark: LOOP WAS VECTORIZED.

bash-3.2$ ./mm_openmp 1024 1
N=1024   P=1
Computation time = 7.5631
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 2
N=1024   P=2
Computation time = 3.8956
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 3
N=1024   P=3
Computation time = 2.5625
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 4
N=1024   P=4
Computation time = 1.9317
c[0,0]=20.480278


б) с перестановкой

Код:
bash-3.2$ icc -O3 -openmp -o mm_openmp mm_openmp.c
mm_openmp.c(34): (col. 3) remark: OpenMP DEFINED LOOP WAS PARALLELIZED.
mm_openmp.c(24): (col. 3) remark: LOOP WAS VECTORIZED.
mm_openmp.c(38): (col. 6) remark: LOOP WAS VECTORIZED.

bash-3.2$ ./mm_openmp 1024 1
N=1024   P=1
Computation time = 0.2811
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 2
N=1024   P=2
Computation time = 0.1651
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 3
N=1024   P=3
Computation time = 0.1120
c[0,0]=20.480278
bash-3.2$ ./mm_openmp 1024 4
N=1024   P=4
Computation time = 0.0877
c[0,0]=20.480278


И чтобы это значило ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: gcc + OpenMP
СообщениеДобавлено: 7 апр 10 18:03 
Не в сети

Зарегистрирован: 23 ноя 09 16:30
Сообщения: 19
Сделайте приватной переменную "i" в #pragma. У вас получается, что в разных тредах она может быть одинаковой.
Скорее всего intel увидел это и сам оптимизировал, а gcc нет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: gcc + OpenMP
СообщениеДобавлено: 8 апр 10 15:53 
Не в сети

Зарегистрирован: 28 май 07 12:10
Сообщения: 47
Откуда: ИПС РАН
Переменная i делается private автоматически:

Цитата:
The for loop iteration variable is implicitly made private in scope for the duration of loop execution


Другое дело, что, как оказалось, все остальные переменные под основной конструкцией for, которые не должны "пересекаться", обязательно нужно описывать как private,т.е., в данном случае, j и k - это и помогло
(заметим, тем не менее, что когда внутренние циклы следуют в обычном порядке, то всё работает правильно - это-то меня и сбило ...).

Другой способ сделать тоже самое состоит в том, чтобы написать так :

Код:
#pragma omp parallel for
  for ( int i=0; i<N; i++)
   for ( int k = 0; k < N; k++)
    for ( int j=0; j<N; j++)     
     c[i*N+j]+=a[i*N+k]*b[k*N+j];


т.е., объявить переменные j и k действительно "новыми".

Возможно, еще есть некоторые нюансы в использовании omp parallel vs omp for, но в этом уже неохота копаться ...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: gcc + OpenMP
СообщениеДобавлено: 23 фев 15 14:57 
Не в сети

Зарегистрирован: 23 фев 15 14:34
Сообщения: 1
Другое дело, что, как оказалось, все остальные переменные под основной конструкцией for, которые не должны "пересекаться", обязательно нужно описывать как private,т.е., в данном случае, j и k - это и помогло

_________________
http://www.rc.edu/
http://www.test-king.com/cert-CCNA-Routing-and-Switching.htm
http://www.test-king.com/cert-RHCSA.htm
http://www.ptsem.edu/
http://en.wikipedia.org/wiki/Berkeley_College


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Часовой пояс: UTC + 4 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB