Дундын хувьсагч

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

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

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

       Shared x As Number эсвэл int x

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

Shared түлхүүр үг

засварлах

Хэрэглээ

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

Санамж

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

Private түлхүүр үг

засварлах

Хэрэглээ

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

Санамж

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

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

засварлах

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

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

  • Дундын хувьсагч нь санах ойд статик байдлаар байршина.
  • Динамикаар байршсан обьектууд дундын байна.
  • Автоматаар хадгалагдсан хувьсагч нь хувийнх байна.

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

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;  
}