Има ли някакъв разделител на обхвата по подразбиране в 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[] на long[] ), няма разлика.


person sthbuilder    schedule 11.02.2015    source източник
comment
Въпросът ви е малко объркващ. Отговарям на двата ви въпроса в края на вашия въпрос. Вашето заглавие обаче е Има ли някакъв разделител на обхвата по подразбиране в OpenMP?. Това е друг въпрос. Какво имате предвид под разделител на обхват?   -  person Z boson    schedule 12.02.2015


Отговори (1)


Вашият код вероятно е неуспешен, защото използвате автоматично съхранение. Трябва да използвате динамично или статично съхранение. Ето корекция на вашия код, използвайки статично съхранение

#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).

person Z boson    schedule 12.02.2015
comment
бихте ли обяснили малко за автоматичното съхранение? цялата глобална променлива върви ли по този начин по подразбиране? и когато казвате статично разпределен буфер, имате ли предвид cprivate матрицата, която използвах? Нарича се статично разпределен, защото декларирам.матрицата с размера на матрицата директно? - person sthbuilder; 12.02.2015
comment
Автоматичното съхранение използва стека, който има ограничен размер. Във вашия код matrixa, matrixb, matric, cprivate всички разпределят от стека. Глобалните променливи и променливите, дефинирани чрез ключовата дума static, използват статично хранилище. - person Z boson; 12.02.2015
comment
Няма нужда от cprivate и затова го премахнах. Въпреки това, ако наистина искате частен буфер за всяка нишка, тогава трябва да използвате malloc за разпределяне с помощта на купчината или threadprivate за статично съхранение за всяка нишка. - person Z boson; 12.02.2015
comment
@javarookie, причината да използвам статично разпределение е просто, за да мога да използвам същата нотация. В противен случай с динамичното разпределение трябва да направите напр. matrixa[i*ASIZE+k]*matrixb[k*ASIZE+j]. - person Z boson; 12.02.2015