Дундын хувьсагч
Дундын хувьсагч нь програмын үндсэн хэсэг, түүний дэд хэсгийн бүх хувьсагчийн утгыг хадгалахын тулд санах ойн нэг үүрийг ашиглана. Дундын хувьсагчийг ашиглахдаа програмын үндсэн хэсэгт дараах байдлаар/маягаар/ зарлаж өгдөг.
Програмчлалын хэл | Хувьсагч зарлалт | Утга олголт |
---|---|---|
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;
}