Дундын хувьсагч (Shared Variables) засварлах

Дундын хувьсагч нь програмын үндсэн хэсэг, түүний дэд хэсгийн бүх хувьсагчийг хадгалахын тулд санах ойн нэг үүрийг ашиглана. Дундын хувьсагчийг ашиглахдаа програмын үндсэн хэсэгт дараах байдлаар/маягаар/ зарлаж өгдөг.

Програмчлалын хэл Хувьсагч зарлалт Утга олголт
Дундын хувьсагчийн үндсэн синтакс
OpenMP Shared x As Number x = 1000
C int x x = 1000

Харин дэд хэсгүүдэд дараах байдлаар/маягаар/ зарлаж өгдөг. Жишээ нь:

       Shared x As Number эсвэл int x

Дундын хувьсагчийг ашиглахын тулд програмын үндсэн болон дэд хэсгүүдэд хэрэглэгдэхээс өмнө зарлаж, утга олгох шаардлагатай байдаг.

Shared түлхүүр үг засварлах

Хэрэглээ

  • Shared(дундын) түлхүүр үг нь өөрийн жагсаалтан дахь хувьсагчийг аль ч хуулбар процест нээлттэй буюу дундын байхыг заана.

Санамж

  • Дундын(shared) хувьсагч санах ойн зөвхөн нэг хаяган дээр байрлах ба бүх хуулбар процесс санах ойн хаягийн утгыг уншиж, бичиж болно.
  • Хос хуулбар процесс дундын хувьсагчид саадгүй хандаж байхыг хянах нь програмистийн үүрэг хариуцлага юм.

Private түлхүүр үг засварлах

Хэрэглээ

  • Private(хувийн) түлхүүр үг нь өөрийн жагсаалтан дахь хувьсагчийг аль ч хуулбар процессоос хаагдмал байхыг заана.

Санамж

  • Ижил төрөлтэй шинэ обьект нь аль ч хуулбар процессын хувьд нэг л удаа зарлагдана.
  • Жинхэнэ обьектын бүх заагч нь шинэ обьектын заагчтай цуг байрлана.
  • Хувийн хувьсагчид аль ч хуулбар процесс дотор анхны утга олгогдоогүй байх хэрэгтэй.

Зэрэгцээ /parallel/ орчны дундын ба хувийн хувьсагч засварлах

Зэрэгцээ орчны хувьсагч дундын эсвэл хувийн аль нь ч байсан болно. Дундын хувьсагчийг паралель мужид тодорхойлохоос гадна бүх хуулбар процесс нэгэн зэрэг хандаж болно. Харин хувийн хувьсагч нь аль ч хуулбар процессоос нуугдмал байдаг.

Хувьсагчийн анхны төлөв дараах байдлаар тодорхойлогдоно. Үүнд:

  • Дундын хувьсагч нь санах ойд статик байдлаар байршина.
  • Динамикаар байршсан обьектууд дундын байна.
  • Автоматаар хадгалагдсан хувьсагч нь хувийнх байна.
  • Heap санах ойд байршсан хувьсагч дундынх байхаас гадна зөвхөн ганц л дундын heap байна.
  • Бүх хувьсагч зэрэгцээ зарлалтын гадна тодорхойлогдоно.

Дараах кодын хэсэг нь анхдагч дүрмүүдийн жишээг харуулж байна:

int E1;                        /* дундын статик хувьсагч */
void main (argvc,...) {        /* argvc нь дундын */
   int i;                      /* автоматаар дундын хувьсагч болно */
void *p = malloc(...);         /* malloc-аар санах ойд байршина */
                               /* бүх хуулбар процессоос хандах боломжтой */
                               /* ба хувийн байж болохгүй */
#pragma omp parallel firstprivate (p)
   {
     int b;                     /* автоматаар хувийн хувьсагч */
     static int s;              /* статик дундын хувьсагч */

     #pragma omp for
     for (i =0;...) {
       b = 1;                   /* b одоо болтол хувийн хувьсагч! */
       foo (i);                 /* i нь хувийн хувьсагч учир */
                                /* I нь энэ давталтын хувьсагч */
      }
#pragma omp parallel
     {
       b = 1;                   /* b хувьсагч энэ тохиолдолд дундынх */
                                /* учир нь програмын өөр хэсэгт ашиглагдаж байна */
     }
   }
 }
int E2;                         /* статик дундын хувьсагч */ 
void foo (int x) {              /* зэрэгцээ хэсэгт х хувьсагч хувийн */
int c;                          /* */
 ... }

Дараах код нь for давталтыг зэрэгцээгээр ажиллуулах жишээ юм. Энэ жишээнд thread_id болон nloops нь хувийн хувьсагч болохыг харж болно. OpenMP -д for давталтыг зэрэгцээ ажиллуулах нь маш энгийн байдаг. Давталт дахь тоолуурууд (энэ тохиолдолд хувьсагч i) хувийн хувьсагчид байхаар зарлагдсан байна.

#include <stdio.h>
#include <omp.h>
int main(int argc, char **argv) 
{
  int i, thread_id, nloops;
  #pragma omp parallel private(thread_id, nloops) 
  {
    nloops = 0;
     #pragma omp for
     for (i=0; i<1000; ++i) 
     {
        ++nloops; 
     }
    thread_id = omp_get_thread_num();
    printf("Thread %d performed %d iterations of the loop.\n",
           thread_id, nloops ); 
  }
  return 0;  
}
SW14E001 (talk) 17:58, 12 Арваннэгдүгээр сар 2014 (UTC)