- •Isbn 978-601-217-247-8
- •Есептеу машиналары
- •§1.1.1 Параллель виртуалды машиналар
- •1 Сурет. Vm/sp, vм/ха, vn/еsа машиналары
- •2 Сурет. Виртуалды машина жүйесі
- •3 Сурет. VMware терезесі
- •4 Сурет. Бір компьютерде бірнеше операциялық жүйе
- •5 Сурет. Вм консолынің мысалы
- •6 Сурет. Виртуалды машиналар жүйесінің архитектурасы
- •§1.1.2 Виртуалды машиналардың түрлері
- •§1.1.3 Виртуаландыру - ақпараттық жүйелерді реттеудің басты жолы
- •§1.2.1 Компьютердің аппараттық құрылымын жетілдіру
- •7 Сурет. Бір операцияны бес тактіде орындайтын тізбекті құрылғының
- •8 Сурет. Бір операцияны әрбірі бес тактіде орындайтын екі бірдей тізбекті
- •10 Сурет. Конвейерлік құрылғы өнімділігінің кіріс деректер
- •11 Сурет. Illiac IV матрицалық жүйесінің жобасы
- •§1.2.2 Компьютерді басқарудың интеллектуалдығын жоғарылату
- •12 Сурет. Ортақ жадылы параллель компьютерлер
- •13 Сурет. Таратылған жадылы параллель компьютерлер
- •14 Сурет. Ортақ шиналы мультипроцессорлық жүйе.
- •15 Сурет. Матрицалық коммутаторлардағы
- •16 Сурет. Омега - желі мультипроцессорлық жүйесі.
- •17 Сурет. Мультикомпьютерлерлік жүйелер байланыс топологияларымен: а – сызықша; б – дөңгелек; в – жұлдызша
- •18 Сурет. Процессорлардың байланыс топологияларының нұсқалары
- •19 Сурет. Сm* есептеу жүйесінің сызбасы
- •20 Сурет. Bbn Butterfly есептеу жүйесінің сызбасы
- •§1.2.3 Функционалды құрылғылар жүйесі
- •§1.3.1 Параллель компьютерлер және жүйелер классификациясы
- •21 Сурет. М. Флин классификациясының sisd және simd кластары
- •22 Сурет. М. Флин классификациясының misd және mimd кластары
- •23 Сурет. Mimd класына р. Хокнидың қосымша
- •§1.3.2 Векторлы-конвейерлік компьютелер
- •24 Сурет. Cray c90 компьютерінің жалпы сүлбесі
- •25 Сурет. Cray c90 компьютері жадысының бөлінуі
- •26 Сурет. Cray c90 компьютерінде векторлық операциялардың орындалуы
- •27 Сурет. Cray c90 компьютерінде векторлық операциялардың ілінісуі
- •§1.3.3 Ортақ жадылы параллель компьютерлер
- •28 Сурет. Hewlett Packard Superdome компьютері
- •29 Сурет. Hewlett Packard Superdome компьютерінің
- •§1.3.4 Таратылған жадылы есептеу жүйелері
- •30 Сурет. Cray t3e компьютерінің коммуникациялық торы
- •31 Сурет. Cray т3d/t3e компьютерлеріндегі барьерлі синхрондау
- •32 Сурет. Есептеу кластерінің жалпы схемасы
- •33 Сурет. Мвс-1000м суперкомпьютерінің құрылымы
- •34 Сурет. Коммуникациялық ортаның латенттілігі және өткізу қабілеті
- •§1.3.5 Метакомпьютинг
- •§2.1.1 Үлкен есептер және үлкен компьютерлер
- •35 Сурет. Сандық эксперименттің этаптары
- •§ 2.1.2 Алгоритм графы және параллель есептеулер
- •§ 2.1.3 Шексіз параллелділік концепциясы
- •§ 2.1.4 Ішкі параллельділік
- •37 Сурет. Матрицаларды көбейту графы
- •38 Сурет. Үшбұрышты жүйелерге арналған графтар
- •39 Сурет. Блокты-екідиагоналды жүйеге арналған Макрограф
- •40 Сурет. Блокты-екідиагоналды жүйеге арналған граф
- •41 Сурет. Жалпыланған пралллель форманың ярустары
- •42 Сурет. Графтағы микро және макропараллельділік
- •§2.2.1 Дәстүрлі тізбекті тілдерді пайдалану.
- •§2.2.2 OpenMp бағдарламалау технологиясы
- •44 Сурет. ОреnМр: бағдарламаның орындалу процесі
- •§2.2.3 Хабарлама жіберу негізіндегі бағдарламалау жүйелері. Mpi бағдарламалау жүйесі
- •Int mpi_Comm_rank(mpi_Comm comm, int *rank)
- •Int mpi_Send(void *buf, int count, mpi_Datatype datatype, int dest, int msgtag, mpi_Comm comm)
- •Integer count, datatype, dest, msgtag, comm, request, ierr
- •Int mpi_Isend(void *buf, int count, mpi_Datatype datatype, int dest, int msgtag, mpi_Comm comm, mpi_Request *request)
- •Int mpi_Irecv(void *buf, int count, mpi_Datatype datatype, int source, int msgtag, mpi_Comm comm, mpi_Request *request)
- •Integer count, datatype, source, msgtag, comm, request, ierr
- •Int main(argc,argv)
- •Int argc;
- •Include 'mpif.H’
- •Integer ierr, rank, size, prev, next, reqs(4), buf(2)
- •Integer stats(mpi_status_size, 4)
- •Int mpi_Waitany( int count, mpi_Request *requests, int *index, mpi_Status *status)
- •Integer count, requests(*), index, status(mpi_status_size), ierr
- •Int mpi_Waitsome( int incount, mpi_Request *requests, int *outcount, int *indexes, mpi_Status *statuses)
- •Integer incount, requests(*), outcount, indexes(*), ierr,
- •Int mpi_Test(mpi_Request *request, int *flag, mpi_Status *status)
- •Integer request, ierr, status(mpi_status_size)
- •Int mpi_Testall( int count, mpi_Request *requests, int *flag, mpi_Status *statuses)
- •Integer count, requests(*), statuses(mpi_status_size,*), ierr
- •Int mpi_Testany(int count, mpi_Request *requests, int *index, int *flag, mpi_Status *status)
- •Integer count, requests(*), index, status(mpi_status_size), ierr
- •Int mpi_Testsome( int incount, mpi_Request *requests, int *outcount, int *indexes, mpi_Status *statuses)
- •Integer incount, requests(*), outcount, indexes(*), ierr,
- •Int mpi_Iprobe( int source, int msgtag, mpi_Comm comm, int *flag, mpi_Status *status)
- •Include 'mpif.H’
- •Integer ierr, rank, size, n, nl, I, j
- •Integer irr, status(mpi_status_size), req(maxproc*2)
- •If(ir .Ne. Rank)
- •Int mpi_Send_init( void *buf, int count, mpi_Datatype datatype, int dest, int msgtag, mpi_Comm comm, mpi_Request *request)
- •Integer count, datatype, dest, msgtag, comm, request, ierr
- •Int mpi_Recv_init( void *buf, int count, mpi_Datatype datatype, int source, int msgtag, mpi_Comm comm, mpi_Request *request)
- •Integer count, datatype, source, msgtag, comm, request, ierr
- •Integer сомм, ierr
- •Include 'mpif.H’
- •Integer ibuf(maxproc)
- •Integer req(2*maxproc), statuses(mpi_status_size, maxproc)
- •Integer count, datatype, root, comm, ierr
- •Integer scount, stype, rcount, rtype, root, comm, ierr
- •Integer scount, stype, rcounts(*), displs(*), rtype, root, comm, ierr
- •Integer scount, stype, rcount, rtype, root, comm, ierr
- •Int mpi_Bcast(void *buf, int count, mpi_Datatype datatype, int source, mpi_Comm comm)
- •Int mpi_Gather( void *sbuf, int scount, mpi_Datatype stype, void *rbuf, int rcount, mpi_Datatype rtype, int dest, mpi_Comm comm)
- •Int mpi_Scatter(void *sbuf, int scount, mpi_Datatype stype, void *rbuf, int rcount, mpi_Datatype rtype, int source, mpi_Comm comm)
- •Int main(argc,argv)
- •Int argc;
- •Int numtasks, rank, sendcount, recvcount, source;
- •Int mpi_Barrier (mpi_Comm comm)
- •§ 2.2.4 Бағдарламалаудың басқа тілдері және жүйелері.
- •Параллель есептеуде қолданылатын қысқаша қазақша-орысша терминологиялық сөздік
- •Параллель есептеуде қолданылатын қысқаша орысша-қазақша терминологиялық сөздік
- •Және орта айнымалылары
- •Mpi функциялары
§2.2.1 Дәстүрлі тізбекті тілдерді пайдалану.
Параллель есептеу жүйелерінің көптеген пайдаланушылары қуана келісетін нұсқа – ол әрине дәстүрлі тізбекті бағдарламалау тілдерін пайдалану. Бұл нұсқа идеалды болмағанымен оның көп артықшылықтары бар. Біріншіден, осы уақытқа дейін құрылған бағдарламалар багажы толық сақталады, екіншіден бағдарламашы үйреншікті терминдерде ойлауын жалғастыра алады, ал бағдарламаның параллель компьютер архитектурасына бейімделуіне қатысты барлық қосымша жұмыстарды компилятор орындайды. Бір қарағанда бәрі жеңіл, нақты орындалатын секілді көрінгенімен, мұнда компилятордың бағдарламаны автоматты түрде параллельдеу процесіне көңіл аударылуы керек.
Біз таратылған жадылы параллель компьютер үшін тиімді бағдарлама алғымыз келді делік. Негізгі есеп те осыған келіп тіреледі. Қандай да бір орындалатын кодты алу аса қиындықтар тудырмайды, ол үшін жай ғана бір процессор үшін бағдарламаны компиляция жасаса жеткілікті. Егер жүктеу кезінде бір ғана процессор қолданылып, бағдарламаның жұмыс уақыты азаймайтын болса онда параллель компьютерді пайдаланып қажет не?
Берілген архитектураның потенциалын толық пайдалану үшін, негізгі үш есепті шешу қажет:
бағдарламада, параллель орындауға болатын есептеу тармақтарын табу;
процессорлардың жергілікті жадыларының модульдеріне деректерді тарату;
деректерді таратуды есептеу параллельдігімен үйлестіру.
Егер бірінші есеп шешілмесе, онда компьютердің көппроцессорлы конфигурациясын пайдаланудың ешқандай мағынасы болмайды. Егер бірінші есеп шешіліп, ал қалған екеуі шешілмесе, онда бағдарламаның барлық жұмыс уақыты процессорлар арасындағы деректермен алмасуға кетуі мүмкін. Бұл жағдайда, бағдарламаның масштабталуы туралы ойды ұмытуға тура келеді.
Көрсетілген есептер шынында да өте күрделі. Бірнеше нақты мысал қарастырғаннан кейін, әркімнің де оған көзі жетері анық.
Енді аталған ситуацияны шамалы ықшамдап көрейік және ортақ жадылы параллель компьютерлерді қарастырайық. Мұнда тек бағдарламаның параллельдігін анықтау есебі ғана қалатындай болып көрінеді, бірақ бәрі сонымен шектеле ме? Бағдарламаның үш жолдан ғана тұратын келесі фрагментін қарастырайық:
DO 10 i = 1, n
DO 10 j = 1, n
10 U(i + j) = U(2*n -i-j+1) * q + p
Берілген циклді конструкцияның қандай итерациялары өзара тәуелсіз болады және фрагментті параллель орындауға болады ма? Фрагменттің ақпараттық құрылымы n = 10 жағдайы үшін 43-ші суретінде көрсетілген.
45 сурет. Фрагменттің ақпараттық құрылымы, n = 10.
Суреттен циклдардың параллель еместігін бірден анықтауға болады. Алайда берілген фрагменттің ішкі екі циклдары параллель болатындай етіп түрлендіруге болатыны байқалады.
DO 10 i = 1, n
DO 20 j = 1, n - i
20 U(i + j) = U(2*n - i - j + l)*q + p
DO 30 j = n - i + 1, n
30 U(i + j) = U(2*n - i - j + l)*q + p
10 continue .
Егер берілген фрагментті (n = 1000) векторлы-конвейерлік Cray С90 компьютерінде (шектік өнімділігі 1 Гфлопс) орындаса, онда оның өнімділігі 20 Мфлопс құрайды [10]. Төмен өнімділіктің негізгі себебі, компилятор, ішкі циклдарының барлық итерациялары өзара тәуелсіз болатын фрагменттің эквивалентті формасын өз бетінше таба алмауында, яғни ол фрагментті векторлай алмайды. Сонымен қатар өзгертілген фрагментте, дәл осы компьютердің өнімділігі шамамен 420 Мфлопс құрайтынын көреміз. Бұдан шығатын қорытынды, фрагмент бар болғаны үш жолдан тұрғанымен ондағы параллельділікті анықтау оңай бола бермейді.
Енді келесі фрагментті қарастырайық:
DO 10 i = 1, n 10 U(i) = Func(U, i)
мұндағы Func – пайдаланушы функциясы. «Цикл итерациялары өзара тәуелсіз бе, әлде жоқ па» деген сұраққа жауап беру үшін, компилятор Func функциясы U массив элементтерін пайдалана ма, жоқ па екенін анықтап алу керек. Егер функция денесінің қандай да бір жерінде, мысалы U(i-1) элементі орындалатын болса, онда итерациялар тәуелді болғаны. Егер Func функциясының өзі айқын түрде U массивін пайдаланбаса, бірақ оның денесінің қандай да бір жерінде басқа функцияны шақыру тұрса және ол өз кезегінде U(i-1) элементін пайдаланатын болса, онда цикл итерациялары тағы да тәуелді болғаны. Жалпы жағдайда, компилятор еркін ұзындықты шақырулар тізбегіне талдау жасай білуі және толық процедура-аралық талдауды орындай алуы керек. Жекелеген жағдайларда бұны істеуге болады, ал жалпы бұл есеп өте күрделі десе болады.
Ал енді компилятор, келесі фрагменттің итерацияларының тәуелсіздігі туралы қандай қорытынды жасауы мүмкін:
DO 10 i = 1, n 10 U(i) = A(i) + U(IU(i) )
Егер IU массиві элементтерінің мәндері туралы ешқандай жорамал ақпараттар жоқ болса, ал ол көбіне болмайды, онда анық ештеңе айта алмаймыз. Параллель іске асыру нәтиженің өзгеруіне алып келуі мүмкін, сондықтан «сенімділік» үшін компилятор тізбекті кодты генерация жасайды. Компилятор нашар ма? Әрине жоқ, тек дәл осы жағдайда ол ештеңе де істей алмайды. Осыған ұқсас, фрагменттің шынайы құрылымын анықтау компиляторға күрделі болатын, олай болса тиімді параллель іске асыру да күрделі болатын мысалдарды көптеп келтіруге болады. Туындайтын мәселелерді шешу қабілеті төмен деп әрине компиляторды кіналап қажеті жоқ. Практика емес теория жүзінде де бағдарламалау тілінің заңдылықтарына сәйкес жазылған еркін фрагментті толықтай талдаудан өткізу мүмкін емес. Егер компьютерлердің архитектурасы күрделі болмаса, онда компиляторлар дәстүрлі тізбекті бағдарламалардан да тиімді кодтарды генерациялауға толық жағдайлары бар. Кері жағдайда компиляторға бағдарламаның қайсібір қасиеттеріне сілтеме жасайтын «жөн сілтеулер» қажет.
Компиляторға жөн сілтеулер әртүрлі формада өрнектелуі мүмкін. Бір жағдайларда комментарийлермен жазылған арнайы директивалар пайдаланылады, келесі бір жағдайларда тілге жаңа конструкциялар енгізіледі, көбіне қосымша қызметтік функциялар пайдаланылады. Типтік байланыс: дәстүрлі тізбекті тіл + қарастырылған тәсілдердің қандай да бір комбинациясы. Бағдарлама текстіне комментариилерімен арнайы директиваларды пайдалануға негізделген параллель компьютерлермен жұмыс істеуге арналған ең танымал Fortran тілінің кеңейтілімінің бірі - High Performance Fortran (HPF). Өткен ғасырдың 90-шы жылдарының ортасында HPF-ке үлкен үміт артылған болатын, өйткені бұл тіл бірден тасымалданатын параллель бағдарламаларды құрастыруға бағытталған болатын. HPF пайда болу уақыты компьютерлердің массалық параллельдігінің даму периодымен дәл келіп, ол кезде бағдарламалардың тасымалдану мәселесі өте өзекті мәселе болды. Алайда бұл жол қабылданбады, себебі HPF конструкциясының күрделілігі оны тиімді компиляторларды құру жолындағы алынбас қамалға айналдырды десе болады.
