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

Чөлөөт нэвтэрхий толь — Википедиагаас
Jump to navigation Jump to search

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

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

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

       Shared x As Number эсвэл int x

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

Shared түлхүүр үг[засварлах | edit source]

Хэрэглээ

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

Санамж

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

Private түлхүүр үг[засварлах | edit source]

Хэрэглээ

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

Санамж

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

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

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

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

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

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

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