2015-02-11 5 views
0

Я новичок в OpenMP, просто сделал свою первую попытку, это было умножение матрицы. Мне просто интересно, существует ли разделитель блоков по умолчанию в openMP? следующий мой код:Есть ли разделитель по умолчанию в OpenMP?

#include <stdio.h> 
#include <omp.h> 
#define MAX_THREADS 4 
#define ASIZE 500 

int main() 
{ 
    /*intialization of 2 matrix*/  
    long matrixa [ASIZE][ASIZE]; 
    long matrixb [ASIZE][ASIZE]; 
    long matrixc [ASIZE][ASIZE] = {0}; 
    for(int i=0; i<ASIZE; i++) 
    for(int j=0;j<ASIZE; j++) 
    { 
     matrixa [i][j] = 1; 
     matrixb [i][j] = j; 
    } 

    omp_set_num_threads(MAX_THREADS); 

    #pragma omp parallel 
    { 
    long cprivate [ASIZE][ASIZE] = {0}; 
    #pragma omp for 
    for(int i =0 ;i<ASIZE; i++) 
     for(int j=0; j<ASIZE; j++) 
     for(int k=0; k<ASIZE; k++) 
      cprivate[i][j]+=matrixa[i][k]*matrixb[k][j]; 

    #pragma omp critical 
    for(int i =0 ;i<ASIZE; i++) 
     for(int j=0; j<ASIZE; j++) 
     matrixc[i][j]+=cprivate[i][j]; 

    //#pragma omp barrier 
    if(omp_get_thread_num() ==0) 
     for(int i=0; i<50; i++) 
     printf("Snap of C array %lu \n", matrixc[1][i]); //print out chunk of the first row! 

    } 
} 

Я думал, так причина добавить ли я #pragma omp barrier или нет, я могу получить ожидаемый результат, который должен быть результат после полного исполнения #pragma omp critical блока.

вопросы

@ почему это не имеет никакого значения с или без #pragma omp barrier Любые идеи?

@ Я также заметил, как только я увеличу размер массива до 600 сот, он будет предупреждать ошибку сегментации при выполнении файла .o. Мое первоначальное предположение было из диапазона int (я изменил тип массива из int [] to long []), никакой разницы.

+0

Ваш вопрос немного запутан. Я отвечу на ваши два вопроса в конце вашего вопроса. Тем не менее, ваш заголовок: «Есть ли разделитель по умолчанию в OpenMP?». Это другой вопрос. Что вы подразумеваете под «сменой объема»? –

ответ

0

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

#include <stdio.h> 
#include <stdlib.h> 
#define ASIZE 1000 

long matrixa [ASIZE][ASIZE]; 
long matrixb [ASIZE][ASIZE]; 
long matrixc [ASIZE][ASIZE]; //set to zero by default with static storage 

int main() { 
    for(int i=0; i<ASIZE; i++) { 
     for(int j=0;j<ASIZE; j++) { 
      matrixa [i][j] = 1; 
      matrixb [i][j] = j; 
     } 
    } 

    #pragma omp parallel for 
    for(int i=0 ;i<ASIZE; i++) { 
     for(int j=0; j<ASIZE; j++) { 
      long sum = 0; 
      for(int k=0; k<ASIZE; k++) { 
       sum += matrixa[i][k]*matrixb[k][j]; 
      } 
      matrixc[i][j] = sum; 
     } 
    } 
    for(int i=0; i<50; i++) printf("Snap of C array %lu \n", matrixc[1][i]); 
} 

Если вы хотите статический выделенный буфер для каждого потока, то вам нужно использовать threadprivate иным образом использовать динамическое выделение.

Причина, по которой вам не нужно использовать барьер, заключается в том, что барьер неявный с critical и многими другими конструктами. Чтобы удалить неявный барьер, вы можете использовать в некоторых случаях nowait (например, #pragma omp parallel for nowait).

+0

Не могли бы вы немного рассказать об автоматическом хранении? это глобальная переменная по умолчанию? и когда вы говорите «статически выделенный буфер», do.you означает используемую матрицу cprivate? Он называется статически распределенным из-за того, что я объявляю матрицу с размером матрицы напрямую? – javarookie

+0

Автоматическое хранилище использует стек, который имеет ограниченный размер. В вашем коде 'matrixa, matrixb, matric, cprivate' все выделяются из стека. Глобальные переменные и переменные, определенные с использованием статического ключевого слова, используют статическое хранилище. –

+0

Нет необходимости в 'cprivate', поэтому я удалил его. Однако, если вам действительно нужен отдельный буфер для каждого потока, вы должны использовать 'malloc' для распределения с помощью кучи или' threadprivate' для статического хранения для каждого потока. –

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