Hva er parallell databehandling. Parallell databehandling og matematikkundervisning. Generelle problemer med å løse "store problemer"

Det finnes ulike måter å implementere parallell databehandling på. For eksempel kan hver databehandlingsprosess implementeres som en operativsystemprosess, eller databehandlingsprosesser kan være en samling av utførelsestråder innenfor en enkelt OS-prosess. Parallelle programmer kan utføres fysisk enten sekvensielt på en enkelt prosessor - alternerende i sin tur trinnene i hver beregningsprosess, eller parallelt - allokere en eller flere prosessorer (plassert i nærheten eller distribuert i et datanettverk) til hver beregningsprosess.

Hovedvanskeligheten med å designe parallelle programmer er å sikre riktig sekvens av interaksjoner mellom ulike databehandlingsprosesser, samt koordinering av ressurser som deles mellom prosesser.

Metoder for å synkronisere parallell interaksjon

I noen parallelle programmeringssystemer er dataoverføring mellom komponenter skjult for programmereren (for eksempel ved å bruke en løftemekanisme), mens den i andre må spesifiseres eksplisitt. Eksplisitte interaksjoner kan deles inn i to typer:

Parallelle systemer for meldingsoverføring er ofte lettere å forstå enn systemer med delt minne og anses generelt som en overlegen metode for parallell programmering. Det finnes et bredt spekter av matematiske teorier for studier og analyse av meldingsoverføringssystemer, inkludert aktørmodellen og ulike typer prosesskalkyler. Meldinger kan implementeres effektivt på symmetriske multiprosessorer med eller uten delt sammenhengende minne.

Distribuert minneparallellisme og meldingspasserende parallellisme har forskjellige ytelsesegenskaper. Vanligvis (men ikke alltid) er overheaden til prosessminne og oppgavebyttetid lavere for meldingsoverføringssystemer, men meldingsoverføring er dyrere enn prosedyrekall. Disse forskjellene overskygges ofte av andre faktorer som påvirker ytelsen.

Selvfølgelig, i et slikt system kan du også bruke meldingsoverføringsmetoden eksklusivt, det vil si kjøre en separat prosess på hver prosessor i hver node. I dette tilfellet vil antall prosesser (og tråder) være lik antall prosessorer på alle noder. Denne metoden er enklere (i et parallelt program trenger du bare å øke antall prosesser), men er mindre effektiv, siden prosessorene til samme node vil utveksle meldinger med hverandre som om de var på forskjellige maskiner.

Typiske oppgaver som tillater parallell databehandling

  • kart - utførelse av den samme funksjonen på hvert element i inndatamatrisen, oppnå en rekke beregningsresultater som er like store
  • reduser - utførelse av den samme funksjonen for å legge til bidraget fra hvert element i inngangsdataene til en endelig verdi

Programvareparallellismeverktøy

  • OpenMP er en applikasjonsgrensesnittstandard for parallelle systemer med delt minne.
  • POSIX Threads er en standard for implementering av utførelsestråder.
  • Windows API - flertrådede applikasjoner for C++.
  • PVM (Parallel Virtual Machine) lar deg kombinere et heterogent (men nettverkstilkoblet) sett med datamaskiner til en felles dataressurs.
  • MPI (Message Passing Interface) er en standard for meldingsoverføringssystemer mellom parallelle utførende prosesser.

se også

Skriv en anmeldelse om artikkelen "Parallell Computing"

Litteratur

  • Dictionary of Cybernetics / Redigert av akademiker V. S. Mikhalevich. - 2. - Kiev: Hovedredaksjonen til den ukrainske sovjetiske leksikonet oppkalt etter M. P. Bazhan, 1989. - 751 s. - (C48). - 50 000 eksemplarer. - ISBN 5-88500-008-5.
  • . - IBM RedBook, 1999. - 238 s.(Engelsk)
  • Voevodin V.V., Voevodin Vl. I. Parallell databehandling. - St. Petersburg: BHV-Petersburg, 2002. - 608 s. - ISBN 5-94157-160-7.
  • Olenev N.N.. - M.: Datasenter RAS, 2005. - 80 s. - ISBN 5201098320.

Notater

Linker

  • (Engelsk)
  • (Engelsk)

Et utdrag som karakteriserer Parallel Computing

Hærens ånd er en multiplikator for masse, og gir produktet av makt. Å bestemme og uttrykke verdien av hærens ånd, denne ukjente faktoren, er vitenskapens oppgave.
Denne oppgaven er bare mulig når vi slutter å vilkårlig erstatte i stedet for verdien av hele det ukjente X de forholdene under hvilke makt manifesteres, for eksempel: ordre fra sjefen, våpen osv., tar dem som verdien av multiplikatoren, og gjenkjenne dette ukjente i all sin integritet, det vil si som et større eller mindre ønske om å kjempe og utsette seg selv for fare. Så bare ved å uttrykke kjente historiske fakta i ligninger og ved å sammenligne den relative verdien av dette ukjente kan vi håpe å bestemme selve det ukjente.
Ti personer, bataljoner eller divisjoner, kjempet med femten personer, bataljoner eller divisjoner, beseiret femten, det vil si at de drepte og fanget alle sporløst og selv mistet fire; derfor ble fire ødelagt på den ene siden og femten på den andre. Derfor var fire lik femten, og derfor 4a:=15y. Derfor, w: g/==15:4. Denne ligningen gir ikke verdien av det ukjente, men det gir forholdet mellom to ukjente. Og ved å innordne ulike historiske enheter (kamper, felttog, krigsperioder) under slike ligninger, får vi tallserier der lover må eksistere og kan oppdages.
Den taktiske regelen om at man må handle i massevis når man rykker frem og separat når man trekker seg tilbake, bekrefter ubevisst bare sannheten om at styrken til en hær avhenger av dens ånd. For å lede folk under kanonkulene, trengs det mer disiplin, som bare kan oppnås ved å bevege seg i masser, enn for å bekjempe angripere. Men denne regelen, som mister hærens ånd av syne, viser seg stadig å være feil og er spesielt påfallende i strid med virkeligheten der det er en sterk oppgang eller nedgang i hærens ånd – i alle folkekriger.
Franskmennene, som trakk seg tilbake i 1812, selv om de burde ha forsvart seg hver for seg, ifølge taktikk, krøp sammen, fordi hærens ånd hadde falt så lavt at bare massen holdt hæren sammen. Russerne, tvert imot, ifølge taktikk, burde angripe i massevis, men i virkeligheten er de fragmenterte, fordi ånden er så høy at enkeltpersoner streiker uten ordre fra franskmennene og ikke trenger tvang for å utsette seg for arbeid. og fare.

Den såkalte partisankrigen begynte med fiendens inntog i Smolensk.
Før geriljakrigføring ble offisielt akseptert av vår regjering, ble tusenvis av mennesker fra fiendens hær - tilbakestående plyndrere, foragerere - utryddet av kosakkene og bøndene, som slo disse menneskene like ubevisst som hunder ubevisst dreper en rabiat hund på flukt. Denis Davydov, med sitt russiske instinkt, var den første som forsto betydningen av den forferdelige klubben, som, uten å spørre reglene for militærkunst, ødela franskmennene, og han er kreditert for å ha tatt det første skrittet for å legitimere denne krigsmetoden.
24. august ble Davydovs første partisanavdeling opprettet, og etter hans løsrivelse begynte andre å bli etablert. Jo lenger kampanjen gikk, desto mer økte antallet av disse avdelingene.
Partisanene ødela den store hæren bit for bit. De plukket opp de falne bladene som falt av seg selv fra det visne treet - den franske hæren, og noen ganger ristet de dette treet. I oktober, mens franskmennene flyktet til Smolensk, var det hundrevis av disse partiene av ulik størrelse og karakter. Det var partier som tok i bruk alle hærens teknikker, med infanteri, artilleri, hovedkvarter og livets bekvemmeligheter; det var bare kosakker og kavaleri; det var små, prefabrikkerte, til fots og til hest, det var bonde- og godseiere, ukjente for noen. Det var en seksmann som leder for partiet, som tok flere hundre fanger i måneden. Det var den eldste Vasilisa, som drepte hundrevis av franskmenn.
De siste dagene av oktober var høydepunktet for partisankrigen. Den første perioden av denne krigen, hvor partisanene, selv overrasket over sin frekkhet, var redde i hvert øyeblikk for å bli fanget og omringet av franskmennene, og uten å sette seg opp eller nesten gå av hestene gjemte de seg i skogene og ventet en forfølgelse. i hvert øyeblikk, har allerede gått. Nå var denne krigen allerede definert, det ble klart for alle hva som kunne gjøres med franskmennene og hva som ikke kunne gjøres. Nå var det bare de avdelingssjefene som med hovedkvarteret deres, i henhold til reglene, gikk bort fra franskmennene, anså mange ting som umulige. De små partisanene, som for lengst hadde begynt sitt arbeid og fulgte nøye med på franskmennene, anså det som mulig det lederne av store avdelinger ikke turte å tenke på. Kosakkene og mennene som klatret blant franskmennene trodde at nå var alt mulig.
Den 22. oktober var Denisov, som var en av partisanene, med sitt parti midt i partisanlidenskapen. Om morgenen var han og hans følge på farten. Hele dagen lang, gjennom skogene ved siden av riksveien, fulgte han en stor fransk transport av kavaleriutstyr og russiske fanger, adskilt fra andre tropper og under sterkt dekke, som kjent fra spioner og fanger, på vei mot Smolensk. Denne transporten var ikke bare kjent for Denisov og Dolokhov (også en partisan med et lite parti), som gikk nær Denisov, men også for sjefene for store avdelinger med hovedkvarter: alle visste om denne transporten og, som Denisov sa, skjerpet deres tenner på den. To av disse store avdelingslederne - den ene polakken, den andre tyskeren - sendte nesten samtidig Denisov en invitasjon til å slutte seg til hver sin avdeling for å angripe transporten.
"Nei, bg"at, jeg har bart selv," sa Denisov, etter å ha lest disse papirene, og skrev til tyskeren at til tross for det åndelige ønske om at han måtte tjene under kommando av en så tapper og berømt general , han må frata seg selv denne lykken, fordi han allerede hadde gått inn under kommando av en polsk general. Han skrev det samme til den polske generalen, og ga ham beskjed om at han allerede var kommet inn under kommando av en tysker.
Etter å ha beordret dette, hadde Denisov til hensikt, uten å rapportere dette til de øverste sjefene, sammen med Dolokhov, å angripe og ta denne transporten med sine egne små styrker. Transporten gikk 22. oktober fra landsbyen Mikulina til landsbyen Shamsheva. På venstre side av veien fra Mikulin til Shamshev var det store skoger som noen steder nærmet seg selve veien, andre en mil eller mer unna veien. Gjennom disse skogene hele dagen lang, nå dypere inn i midten av dem, nå på vei til kanten, syklet han med Denisovs parti, og slapp ikke de bevegelige franskmennene ut av syne. Om morgenen, ikke langt fra Mikulin, hvor skogen kom nær veien, fanget kosakker fra Denisovs parti to franske vogner med kavalersadler som var blitt skitne i gjørmen og tok dem med inn i skogen. Fra da til kvelden fulgte partiet, uten å angripe, franskmennenes bevegelse. Det var nødvendig, uten å skremme dem, å la dem rolig nå Shamshev og deretter, forenes med Dolokhov, som skulle ankomme om kvelden for et møte ved vakthuset i skogen (en mil fra Shamshev), ved daggry, falle fra begge sider ut av det blå og slå og ta alle på en gang.
Bak, to mil fra Mikulin, der skogen nærmet seg selve veien, var seks kosakker igjen, som skulle melde fra så snart nye franske kolonner dukket opp.
Foran Shamsheva, på samme måte, måtte Dolokhov utforske veien for å vite i hvilken avstand det fortsatt var andre franske tropper. Ett tusen fem hundre mennesker var forventet å bli transportert. Denisov hadde to hundre mennesker, Dolokhov kunne hatt det samme antallet. Men overlegne tall stoppet ikke Denisov. Det eneste han fortsatt trengte å vite var nøyaktig hva disse troppene var; og for dette formålet trengte Denisov å ta en tunge (det vil si en mann fra fiendens kolonne). I morgenangrepet på vognene ble saken gjort så raskt at franskmennene som var med vognene ble drept og tatt til fange kun av trommeslagergutten, som var tilbakestående og ikke kunne si noe positivt om hva slags tropper i kolonne.
Denisov anså det for farlig å angripe en annen gang, for ikke å skremme hele kolonnen, og derfor sendte han bonden Tikhon Shcherbaty, som var med partiet hans, til Shamshevo for å fange, om mulig, minst en av de franske avanserte kvartererne. som var der.

Multiprosessering og multi-kjerner har lenge blitt vanlig blant brukere, noe som ikke hindrer programmerere fra å ikke fullt ut, eller til og med rett og slett feilaktig bruke egenskapene som ligger i dem. Vi lover ikke at etter å ha lest denne artikkelen vil du bli en guru av parallell databehandling i Win-miljøet, men du vil definitivt forstå noen ting.

Introduksjon

Slutten på æraen med 32-bits steiner nærmet seg, og det var åpenbart at det var nødvendig å øke ikke bare kraften, men også bitkapasiteten. Prosessorutviklere møtte en rekke problemer med å øke klokkefrekvensen: det var umulig å spre varmen generert av krystallen, det var umulig å redusere størrelsen på transistorene ytterligere, men hovedproblemet var at økningen av klokkefrekvensen ikke ble bedre. ytelsen til programmene. Årsaken til dette er parallelldrift av moderne datasystemer, og én prosessor, uansett hvor kraftig den er, kan bare utføre én oppgave om gangen. For eksempel har jeg 119 prosesser som kjører på Windows 7-systemet mitt når dette skrives. Selv om de ikke alle er i bakgrunnen, trenger de ikke alle høy effekt. På en stein kan utførelse av flere prosesser/tråder kun være samtidig. Det vil si at arbeidet deres veksler: etter at en bestemt tråd har fullført sin tidsdel der den har fullført nyttelasten, vil dens nåværende tilstand lagres i minnet, og den vil bli lastet ut fra prosessoren og erstattet av den neste tråden som står i kø for kjøring - en kontekstswitch vil skje, som kostbar tid er bortkastet. I mellomtiden utveksles data mellom prosessoren og RAM; på grunn av den begrensede båndbredden til systembussen, røyker mikroprosessoren nervøst bambus og venter på sidelinjen for data. Maskinvare og programvare (for eksempel fra operativsystemet) planleggere kan komme til unnsetning for å laste data inn i hurtigbufferen. Imidlertid er cachen svært begrenset i størrelse, så denne løsningen kan ikke tjene som et universalmiddel. Løsningen var parallell prosessering, der flere prosesser kjører samtidig i sanntid. Og for å realisere det, var det nødvendig å fundamentalt redesigne og gjenoppbygge steinen - for å kombinere to eller flere utførende krystaller i en kropp.

Planlegger

Når man utvikler et parallelt program, blir designstadiet enda viktigere enn når man utvikler entrådede applikasjoner. Og siden, faktisk, parallell programmering har blitt brukt i flere tiår i et smalt utvalg av problemer, har noen utprøvde konsepter blitt identifisert. Det viktigste er å se på utviklingen annerledes, ikke sekvensielt, for å fremheve en enhet av arbeidet som utføres, og å dekomponere oppgaven. Det er tre metoder: dekomponering etter oppgaver, dekomponering etter data, dekomponering etter informasjonsflyt. Den første dekomponeringsmetoden er den enkleste: vi binder ganske enkelt en egen funksjon til en spesifikk tråd og starter den for utførelse. Parallell behandling er klar. Det kan imidlertid være problemer - strid hvis den kjørbare enheten bruker delte globale data. Men vi skal snakke om dette senere. Den andre metoden er også en ganske klar parallelliseringsmetode: for eksempel behandles et stort utvalg av data av flere tråder, som hver fungerer på en del begrenset av visse grenser. Dekomponering etter informasjonsflyt brukes til oppgaver der arbeidet til en tråd avhenger av resultatet av utførelsen av en annen. For eksempel, når du leser fra en fil, kan ikke tråden som håndterer de leste dataene begynne å fungere før lesertråden leser en viss mengde data.

Maskinvareløsninger


Før de flyttet til flerkjerner, fant prosessorutviklere ut at når de kjører én tråd, er ikke prosessorkjernen fulllastet (jeg tror du ikke trenger å være en visjonær for dette). Og siden ikke alle mikroprosessorressurser brukes til å utføre den andre programtråden (siden maskinvaretilstanden - utøvende enheter, cache - kan lagres i en kopi), trenger bare tilstandsområdet til programvarearkitekturen (avbruddslogikk) duplisering. Denne teknologien kalles hyper-threading. Hyperthreading er en maskinvaremekanisme der flere uavhengige maskinvaretråder kjøres i en enkelt klokkesyklus på en enkelt superskalar prosessorkjerne. Med dens hjelp er en fysisk prosessor representert som to logiske, det vil si at det er slik operativsystemet ser det, fordi planlegging og utførelse faktisk utføres med to kjerner i tankene. Dette skjer takket være en kontinuerlig strøm av kommandoer som kjører på delt maskinvare. Denne teknologien ble lagt til NetBurst-arkitekturen implementert i Pentium 4-prosessorer. Derfor ble hyperthreading implementert i de nyeste versjonene av Pentium 4, men på en eller annen måte klarte jeg ikke å fange det på det tidspunktet. Men nå kan jeg se det i Atom-prosessoren installert i netbooken. I denne steinen er det i tillegg til hyperthreading implementert multikjerner (to stykker), så jeg ser fire steiner i operativsystemet. Men det er for eksempel ingen hyperthreading i Core 2 Duo, så vel som i Core i5. Ved hjelp av hyperthreading ble utførelseshastigheten til programmer optimalisert for multithreading økt med 30 %. Jeg vil presisere at ytelsesgevinsten kun vil oppstå i spesielt utarbeidede søknader.

Samtidig med hyperthreading, i tillegg til superskalararkitekturen, ble det laget en ny EPIC-arkitektur, implementert i Itanium-prosessorer, men dette emnet passer ikke lenger inn i dagens artikkel.

Så ble flerkjerneprosessorer oppfunnet, som nå brukes overalt. Flerkjerneprosessorer støtter multiprosessering på brikken. I denne arkitekturen er to eller flere kjerner implementert i en enkelt prosessor installert i en enkelt sokkel. Avhengig av utformingen kan disse kjernene dele en stor cache på samme die. Multi-core prosessorer krever også et kompatibelt brikkesett. Siden hver kjerne er en uavhengig utførelsesmodul, gir flerkjerneprosessorer ekte parallellitet - utførelsen av hver tråd i et separat miljø. I tilfelle av tilstedeværelsen av flere utførelseskjerner, må det være en måte å utveksle informasjon mellom dem, uten hvilken det rett og slett er umulig å lage et parallelt system, og en spesiell ressurs er nødvendig. For å oppnå dette ble Advanced Programmable Interrupt Controller (APIC) oppfunnet. Den utveksler informasjon mellom prosessorer/kjerner ved hjelp av Interprocessor Interrupt-mekanismen. Sistnevnte brukes på sin side av operativsystemet til å planlegge/utføre tråder.

Energiforbruket kommer også i forgrunnen. Og dette gjelder ikke bare ulike batteridrevne mobile plattformer, men også serversystemer og skrivebord. De første x86-prosessorene forbrukte brøkdeler av en watt, mens dagens high-end-modeller kan forbruke 130 watt eller mer. I mellomtiden sparer flerkjerneprosessorer energi fordi ytelsesgevinster kommer fra parallellitet snarere enn fra økende klokkehastigheter.

Programvareløsninger

Programvareløsninger spiller en stor rolle i parallell kodekjøring. Både systemprogramvareprodukter (operativsystemer, kompilatorer) og applikasjoner på brukernivå kommer inn på scenen. Fra synspunktet til en applikasjonsprogrammerer kan vi bare bruke den andre undergruppen. Faktisk er dette ganske nok hvis operativsystemet er pålitelig. Det meste av det følgende gjelder for Windows NT 6.1, med mindre annet er angitt. Som du vet, bruker Windows NT en forebyggende multithreading-modell. Når en applikasjon starter, starter en prosess der en eller flere tråder kan utføre arbeidet sitt, som alle deler felles minne og felles adresserom. En tråd er på sin side en egen sekvens av kommandoer som utføres uavhengig. Det er tre typer strømmer:

  • brukernivå - opprettet i brukerprogrammet (på brukernivå). Disse trådene i Windows NT er kartlagt til tråder på kjernenivå, som er hvordan prosessoren ser dem;
  • kjernetråd - kontrollert av operativsystemkjernen;
  • maskinvaretråd - en enhet som kjøres på prosessoren.

Opprettelsen av en bekk skjer i tre stadier. Først beskrives det ved å bruke threading API, deretter behandles dette kallet på utførelsesstadiet som et kjernekall, som et resultat opprettes en tråd, deretter kjøres den i sin egen prosess. Men på grunn av det faktum at flere handlinger utføres samtidig i programmet, kan det oppstå mange problemer. De kan enkelt klassifiseres i fire typer. Et synkroniseringsproblem oppstår når en tråd venter på kjøring av en annen, som av en eller annen grunn ikke kan fullføre kjøringen. Når det er et kommunikasjonsproblem, kan ikke en tråd overføre informasjon til en annen i rett tid, for eksempel på grunn av forsinkelser. Når den ene bekken er stresset og den andre er kjølig, oppstår det et balanseringsproblem. Hvis, når et program overføres til en kraftigere datamaskin, ytelsen ikke forbedres, snakker de om et skalerbarhetsproblem. For å løse alle disse problemene er primitiver designet for å fungere i et flertrådsmiljø. La oss ta en rask titt på dem.

Parallelle kodingsprimitiver

Deler av kode som kan brukes samtidig av flere tråder og inneholder delte variabler kalles kritiske deler. I dem kan lese- og skriveverdier under handling av to eller flere tråder forekomme asynkront. Denne tilstanden kalles en racingtilstand. Derfor bør bare én tråd kjøres inne i den kritiske delen ved hvert tidsintervall. For å sikre dette brukes synkroniseringsprimitiver - låsing. Semafor er historisk sett den aller første synkroniseringsmekanismen, utviklet av Dijkstra i 1968. Lar et visst antall tråder gå inn i den kritiske delen; når en tråd går inn i den, reduserer den verdien og øker den i det øyeblikket den avsluttes. En forutsetning er atomutførelsen av operasjonene med å kontrollere verdien av semaforen + øke verdien, samt å kontrollere verdien + redusere verdien. En utvidelse av semaforen er en mutex, som ganske enkelt er en binær semafor og derfor tillater bare én tråd å kjøre i den kritiske delen. Lese-skrive-låser lar flere tråder lese verdien av en delt variabel som ligger i den kritiske delen, men bare skrive til én. Mens du venter, blokkerer ikke spinlocken, men fortsetter aktivt å polle den låste ressursen. Spinlocking er en dårlig løsning på synkroniseringsproblemet på en enkeltkjerneprosessor fordi den tar opp alle dataressursene.

Mekanismen til tilstandsvariabler ligner på semaforer, men i motsetning til semaforer (og mutekser), inneholder de ikke reelle verdier. De overvåker oppfyllelsen av ytre betingelser.

Moderne programmeringsspråk inneholder mekanismer på høyt nivå for å forenkle bruken av låser og betingede variabler ("monitorer"). I stedet for eksplisitt å skrive låse- og opplåsingsoperasjoner på en kodedel, trenger utvikleren bare å erklære den kritiske delen som synkronisert.

For å utveksle informasjon mellom prosesser/tråder brukes meldinger, delt inn i tre grupper: intraprosess (for overføring av informasjon mellom tråder i én prosess), interprosess (for overføring av informasjon mellom prosesser - med avhengighet av tråder) og prosess - prosess (tråduavhengig overføring av informasjon mellom prosesser ).
Samtidig, når du bruker låser for å unngå løp, kan dødlåser og aktive låser oppstå. En dødlås oppstår når en tråd er blokkert og venter på en spesifikk ressurs fra en annen tråd, men den tråden kan ikke gi den (for eksempel venter den på et resultat fra den første). En dødlås kan oppstå når fire veldefinerte betingelser er oppfylt (vi vil ikke dekke disse forholdene i denne artikkelen). Derfor, når du skriver flertrådskode, har programmereren muligheten til å unngå didlock, men i praksis ser det mye vanskeligere ut. Levende låsing er verre enn dødlåsing ved at i det første tilfellet er trådene blokkert, og i det andre er de konstant i konflikt.

Det finnes en rekke inkompatible applikasjonsstrømprogrammeringsgrensesnitt. De bruker i utgangspunktet de samme primitivene, de eneste forskjellene er avhengig av operativsystemet. I de følgende delene skal vi se på måter å jobbe i et flertrådsmiljø og løse samtidighetsproblemer ved å bruke disse grensesnittene.


Win32-tråder

Siden den første versjonen av Windows NT har flertrådsprogrammering blitt forbedret fra versjon til versjon, samtidig som threading API også er forbedret. Så når en prosess startes ved hjelp av CreateProcess-funksjonen, har den én tråd for å utføre kommandoer. En tråd består av to objekter: et kjerneobjekt (som systemet kontrollerer tråden gjennom) og en stabel som lagrer parametrene, funksjonene og variablene til tråden. For å opprette en ekstra tråd, må du kalle opp CreateThread-funksjonen. Dette skaper et kjerneobjekt, en kompakt datastruktur som brukes av systemet for å kontrollere flyten. Dette objektet er faktisk ikke en tråd. Minne tildeles også fra den overordnede prosessens adresserom for tråden. Og siden alle trådene i én prosess vil bli utført i adresseområdet, vil de dele dens globale data. La oss gå tilbake til CreateThread-funksjonen og se på parameterne. Den første parameteren er en peker til PSECURITY-strukturen ATTRIBUTTER, som definerer sikkerhetsattributter og arveegenskaper, kan settes til standardverdier ved å sende NULL. Den andre parameteren av typen DW0RD bestemmer hvilken del av adresserommet tråden kan bruke for stabelen. Tredje parameter PTHREAD START_ROUTIME pfnStartAddr er en peker til funksjonen som må bindes til tråden og som den skal utføre. Denne funksjonen må ha formen DWORD WINAPI ThreadFunc(PVOID pvParam), den kan utføre alle operasjoner; når den er fullført, vil den returnere kontroll, og brukertelleren til trådkjerneobjektet vil bli redusert med 1; hvis denne telleren er lik 0, vil dette objektet bli ødelagt. Den fjerde parameteren til CreateThread-funksjonen er en peker til en PVOID-struktur som inneholder en parameter for initialisering av funksjonen som kjører i tråden (se beskrivelsen av den tredje parameteren). Den femte parameteren (DWORD) spesifiserer et flagg som indikerer om tråden er aktiv etter at den er opprettet. Den siste, sjette parameteren (PDWORD) er adressen til variabelen der trådidentifikatoren skal plasseres; hvis vi passerer NULL, vil vi dermed indikere at vi ikke trenger den. Hvis den lykkes, returnerer funksjonen et strømhåndtak, som kan brukes til å manipulere strømmen; hvis den mislykkes, returnerer funksjonen 0.


Det er fire måter å avslutte en tråd på, hvorav tre er uønskede: avslutte tråden ved å kalle opp ExitThread-funksjonen, ved å kalle TerminateThread, eller ved å avslutte den overordnede prosessen uten først å avslutte tråden. Bare 1 måte - selvavslutningen av strømmen, som oppstår når du utfører handlingene som er tildelt den, er gunstig. For bare i dette tilfellet er det garantert at alle operativsystemressurser vil bli frigjort og alle C/C++-objekter vil bli ødelagt ved hjelp av deres destruktorer.

Noen flere ord om å lage en tråd. CreateThread-funksjonen er i Win32 API, og Visual C++-biblioteket har en ekvivalent, _beginthreadex, som har nesten samme liste over parametere. Det anbefales å lage tråder ved å bruke det, siden det ikke bare bruker CreateThread, men også utfører tilleggsoperasjoner. I tillegg, hvis tråden ble opprettet ved bruk av sistnevnte, kalles _endthreadex når den er ødelagt, som sletter datablokken som er okkupert av strukturen som beskriver tråden.

Tråder er planlagt å kjøre basert på prioritet. Hvis alle tråder hadde samme prioritet, ville 20 ms blitt tildelt for hver tråd (i WinNT). Men det er ikke sant. WinNT har 31 (fra null) trådprioriteter. Samtidig er 31 den høyeste, bare de mest kritiske applikasjonene kan kjøres på den - enhetsdrivere; 0, den laveste, er reservert for å utføre tråden for sidenullstilling. Utvikleren kan imidlertid ikke spesifisere eksplisitt et prioritetsnummer for utførelse av tråden hans. Men i Windows er det en prioritetstabell, der de symbolske betegnelsene til grupperte prioritetsnummer er angitt. I dette tilfellet dannes det endelige tallet ikke bare på grunnlag av denne tabellen, men også på prioritetsverdiene til den overordnede prosessen. Verdiene er skjult bak symbolske konstanter av den grunn at Microsoft forbeholder seg retten til å endre dem og bruker dem fra versjon til versjon av operativsystemet. Når den opprettes, gis en tråd et normalt prioritetsnivå. Den kan endres av funksjonen SetThreadPriority, som tar to parametere: HANDLE hThread - beskrivelse av tråden som endres, int nPriority - prioritetsnivå (fra tabellen). Ved å bruke GetThreadPriority-funksjonen kan du få gjeldende prioritet ved å sende beskrivelsen til ønsket tråd til den. Før du endrer prioriteten til en tråd, må den suspenderes; dette gjøres av SuspendThread-funksjonen. Etter å ha endret prioritet, må tråden gis tilbake til planleggeren for å planlegge utførelse ved hjelp av ResumeThread-funksjonen. Begge funksjonene får et håndtak til tråden de jobber med. Alle beskrevne operasjoner unntatt suspendere og gjenoppta gjelder prosesser. De kan ikke settes på pause/gjenopptas fordi de ikke bruker CPU-tid, så de er ikke planlagt.

Unngå løp i Win32

I flertrådede applikasjoner, når det er mulig, er det nødvendig å bruke atomære - udelelige operasjoner, hvis utførelse ikke kan forstyrres av en annen tråd. Slike funksjoner i Win32 API har Interlocked-prefikset, for eksempel for å øke en variabel, bruk InterlockedExchangeAdd(&i, 1) i stedet for i++. I tillegg til inkrement-/dekrementeringsoperasjoner finnes det også operasjoner for atomsammenligning, men vi vil la dem være hjemmeleksene dine.

Atomfunksjoner lar deg imidlertid løse et veldig smalt spekter av problemer. Kritiske seksjoner kommer til unnsetning. Win32 har funksjoner for eksplisitt å merke et stykke kode som skal kjøres atomisk. Først må du lage en forekomst av den kritiske seksjonsstrukturen, deretter i funksjonen som utføres i tråden, skriv operatorer for å gå inn og ut av den kritiske seksjonen:

CRITICAL_SECTION g_cs; DWORD WINAPI ThreadRun(PVOID pvParam) ( EnterCriticalSection(&g_cs); // Beregn noe LeaveCriticalSection(&g_cs); return 0; )

Kritiske seksjoner i Win32 er ikke bare kode som kan kjøres av flere tråder, de er en hel datasynkroniseringsmekanisme. Kritiske seksjoner bør være så små som mulig, det vil si involvere så få beregninger som mulig.
For å tillate flere tråder å lese verdien av en variabel og bare én å endre den, kan du bruke SRWLock "tynn låsing" struktur. Det første trinnet er å initialisere strukturen ved å kalle InitializeSRWLock og sende en peker til den. Deretter, under opptak, begrenser vi ressursen til eksklusiv tilgang:

AcquireSRWLockExclusive(PSRWLOCK SRWLock); // Skriv verdien ReleaseSRWLockExclusive(PSRWLOCK SRWLock);

På den annen side, mens vi leser, utfører vi delt tilgang:

AcquireSRWLockShared(PSRWLOCK SRWLock); // Les verdien ReleaseSRWLockShared(PSRWLOCK SRWLock);

Vennligst merk: alle funksjoner tar en initialisert SRWLock-struktur som en parameter.
Ved å bruke betingede variabler er det praktisk å organisere forholdet "leverandør-forbruker" (se dekomponering etter informasjonsstrømmer), det vil si at neste hendelse skal skje avhengig av den forrige. Denne mekanismen bruker funksjonene SleepConditionVariableCS og SleepConditionVariableSRW for å låse den kritiske delen eller den tynne låsestrukturen. De tar henholdsvis tre og fire parametere: en peker til en tilstandsvariabel som forventes av tråden, en peker til den kritiske delen eller en SRWLock som brukes for tilgangssynkronisering. Den neste parameteren er tiden (i millisekunder) for tråden å vente på at betingelsen er oppfylt; hvis betingelsen ikke er oppfylt, vil funksjonen returnere False; Den siste parameteren til den andre funksjonen er typen lås. For å vekke blokkerte tråder, må du kalle opp WakeConditionVariable- eller WakeAllConditionVariable-funksjonen fra en annen tråd. Hvis testen utført som et resultat av å kalle disse funksjonene bekrefter oppfyllelsen av betingelsen som er gitt som en parameter til disse funksjonene, vil tråden vekkes.

I beskrivelsen ovenfor ble vi kjent med de generelle definisjonene av semafor- og mutex-mekanismene. La oss nå se hvordan de er implementert i Win32. Du kan lage en semafor ved å bruke CreateSemaphore-funksjonen. Følgende parametere sendes til den: en peker til PSECURITY_ATTRIBUTES-strukturen som inneholder sikkerhetsparametere; maksimalt antall ressurser behandlet av søknaden; mengden av disse ressursene som er tilgjengelige i utgangspunktet; En peker til en streng som definerer navnet på semaforen. Når en tråd som venter på en semafor ønsker å få tilgang til en ressurs som er beskyttet av semaforen, spør trådens ventefunksjon statusen til semaforen. Hvis verdien er større enn 0, er semaforen fri og verdien reduseres med 1, og tråden er planlagt for utførelse. Hvis semaforen er opptatt under polling, er verdien 0, så går den anropende tråden inn i en ventetilstand. I det øyeblikket en tråd forlater semaforen, kalles ReleaseSemaphore-funksjonen, der verdien av semaforen økes med 1. Mutexes, som semaforer, er kjerneobjekter. Funksjonen til mutexes ligner på Win32-kritiske seksjoner, med den forskjellen at sistnevnte kjøres i brukermodus. En mutex lar kun én tråd kjøres om gangen og gir tilgang til kun én ressurs. Samtidig lar den deg synkronisere flere tråder ved å lagre identifikatoren til tråden som fanget opp ressursen og en teller for antall fangst. For å lage en mutex, kan du bruke CreateMutex-funksjonen; dens parametere ligner de som er diskutert ovenfor. Når en tråds ventetid på en mutex fullføres vellykket, får den eksklusiv tilgang til den beskyttede ressursen. Alle andre tråder som forsøker å få tilgang til denne ressursen går inn i en ventetilstand. Når tråden som opptar en ressurs er ferdig med å bruke den, må den frigjøre mutexen ved å kalle ReleaseMutex-funksjonen. Denne funksjonen reduserer rekursjonstelleren i mutexen med 1. Valget av synkroniseringsmekanisme som skal brukes avhenger i stor grad av tidspunktet for dens utførelse og koden den brukes i.

Blant annet i Windows NT, fra den fjerde versjonen, er det et annet trådnivå med detaljer - fibre (eller tråder). På brukernivå kan en kjerneobjekttråd deles opp i flere tråder. Og i dette tilfellet vet operativsystemet ingenting om dem; alt arbeidet med å planlegge og administrere tråder faller på skuldrene til applikasjonsutvikleren.

Konklusjon

Å lage moderne programvare krever bruk av parallellitet, og i fremtiden truer prosessorprodusenter bare med å øke antall kjerner på en enkelt prosessor. Imidlertid har flertrådsprogrammering en rekke vanskelige aspekter: organisere synkron utførelse av kommandoer, unngå løp, og samtidig laste maskinvaren optimalt for å oppnå økt ytelse på grunn av parallellitet.

I denne artikkelen behandlet vi først parallellkodingsprimitiver - generelle konsepter, deretter fant vi ut hvordan de er implementert i et spesifikt API - Win 32 tråder. Omfanget av artikkelen tillot oss ikke å vurdere andre API-er for flertrådskoding. La oss håpe at vi en dag får muligheten til å fortsette å diskutere dette nødvendige temaet.

Jeg ønsker deg lykke til, ses snart!

Send ditt gode arbeid i kunnskapsbasen er enkelt. Bruk skjemaet nedenfor

Studenter, hovedfagsstudenter, unge forskere som bruker kunnskapsbasen i studiene og arbeidet vil være deg veldig takknemlig.

postet på http://www.allbest.ru/

postet på http://www.allbest.ru/

  • Introduksjon
  • 1. Temaets relevans
  • 2. Øke antall kjerner
  • 3. NVIDIA CUDA-teknologi
  • 4. Forskjellen mellom CPU og GPU
  • Konklusjon
  • Introduksjon
  • Parallellisering av beregninger er delingen av store oppgaver i mindre som kan utføres samtidig. Parallell databehandling krever vanligvis en viss koordinert innsats. Parallell databehandling kommer i flere former (instruksjon, bit, data, oppgavenivåer). Parallell databehandling har blitt brukt i mange år hovedsakelig i høyytelses databehandling. Men situasjonen har endret seg i det siste. Det var etterspørsel etter slike beregninger på grunn av fysiske begrensninger på veksten av prosessorens klokkehastighet. Parallell databehandling har blitt en dominerende idé innen dataarkitektur. Det tok form av multi-core prosessorer.
  • Bruken av parallelle datasystemer bestemmes av strategiske utviklingsretninger i dataindustrien. Hovedomstendigheten var ikke bare begrensningen av hastigheten til maskiner basert på sekvensiell logikk, men også tilstedeværelsen av oppgaver som tilgjengeligheten til datateknologi ennå ikke er tilstrekkelig for. Oppgaver i denne kategorien inkluderer modellering av dynamiske prosesser.
  • Fremkomsten av flerkjerneprosessorer markerte et sprang i utviklingen av effektiv superdatabehandling, som kan skryte av høyere ytelse/kostnadsforhold enn superdatamaskinbaserte systemer. Bruken av multi-core prosessorer gir fleksibilitet, spesielt for varierende konfigurasjoner, samt skaleringskraft i datasystemer – fra PCer, servere, arbeidsstasjoner og slutter med klyngesystemer.
  • 1. Temaets relevans
  • De siste årene har det dukket opp et stort antall billige cluster parallelle databehandlingssystemer, noe som har ført til den raske utviklingen av parallell databehandlingsteknologi, inkludert innen høyytelses databehandling. De fleste store mikroprosessorprodusenter begynte å bytte til flerkjernearkitekturer, noe som påvirket endringen i situasjonen innen parallell databehandlingsteknologi. En endring i maskinvarebasen innebærer en endring i konstruksjonen av parallelle algoritmer. For implementering i multi-core databehandlingsarkitekturer trengs nye parallelle algoritmer som tar hensyn til nye teknologier. Effektiviteten av å bruke dataressurser vil avhenge av kvaliteten på de parallelle applikasjonene selv og spesialiserte biblioteker rettet mot flerkjernearkitekturer.
  • Bruken av høyytelsesteknologi for å modellere reelle tekniske, økonomiske og andre prosesser beskrevet av systemer med høydimensjonale vanlige differensialligninger er ikke bare berettiget, men også nødvendig. Parallellisering av beregninger i multiprosessor og parallelle strukturer er en effektiv måte å forbedre ytelsen på. Så bruken av parallelle datasystemer er en ganske viktig retning i utviklingen av datateknologi.

2. Øke antall kjerner

Den første prosessoren for massebruk var POWER4 med to PowerPC-kjerner på en enkelt brikke. Utgitt av IBM i 2001.

Prosessorprodusentene Intel, AMD, IBM, ARM har anerkjent å øke antall kjerner som et av de prioriterte områdene for å øke ytelsen.

I 2011 ble 8-kjerners prosessorer for hjemme-PCer og 16-kjerners prosessorer for serversystemer utgitt.

Det er utviklinger av prosessorer med et stort antall kjerner (mer enn 20), som har funnet applikasjon i spesifikke enheter.

Dual-core prosessorer eksisterte tidligere, for eksempel IBM PowerPC-970MP (G5H). Men slike prosessorer ble brukt i et smalt utvalg av spesialiserte oppgaver.

I april 2005 introduserte AMD den 2-kjernede Opteron-prosessoren. AMD64-arkitektur. designet for servere. I mai 2005 introduserte Intel Pentium D-prosessoren x86-64-arkitektur. Ble den første 2-kjerne prosessoren for hjemme-PCer.

I mars 2010 introduserte AMD 12-kjerners serielle serverprosessorer Opteron 6100 (x86/x86-64-arkitektur).

I august 2011 introduserte AMD serverprosessorene i 16-kjerne Opteron 6200. Interlagos-prosessoren inneholder to 8-kjerners (4-moduler) brikker i en enkelt pakke og er kompatibel med AMD Opteron 6100-seriens plattform (Socket G34).

3. NVIDIA CUDA-teknologi

En stor mengde parallell databehandling er knyttet til 3D-spill. Parallell vektordatabehandling på enheter for generell bruk med flerkjerneprosessorer brukes i 3D-grafikk, og oppnår høy toppytelse. Universelle prosessorer kan ikke gjøre dette. Maksimal hastighet oppnås bare i en rekke praktiske oppgaver, med noen begrensninger. Men fortsatt er slike enheter mye brukt i områder der de ikke opprinnelig var ment. For eksempel Cell-prosessoren, utviklet av Sony-Toshiba-IBM-alliansen i Sony PlayStation 3-spillkonsollen, eller moderne skjermkort fra NVIDIA og AMD.

For noen år siden begynte generelle ikke-grafiske databehandlingsteknologier GPGPU for 3D-videoakseleratorer å dukke opp. Moderne videobrikker har hundrevis av matematiske utførelsesenheter, slik kraft kan bidra betydelig til å øke hastigheten på mange beregningsintensive applikasjoner. De nåværende generasjonene av GPUer har en fleksibel arkitektur, som sammen med programvare- og maskinvarearkitekturer og høynivåspråk gjør det mulig å gjøre dem mye mer tilgjengelige.

Fremveksten av ganske raske og fleksible shader-programmer har interessert utviklere i å lage GPGPU-er som er i stand til å utføre moderne videobrikker. Utviklere ønsket å bruke GPUen til å beregne ikke bare bilder i spill og 3D-applikasjoner, men også å bruke dem i andre områder av parallell databehandling. For å gjøre dette brukte vi API-en til OpenGL- og Direct3D-grafikkbibliotekene. Data ble overført til videobrikken som teksturer, og beregningsprogrammer ble plassert i form av shaders. Den største ulempen med denne metoden er den betydelige kompleksiteten til programmering, lav datautveksling mellom GPU og CPU, og noen andre begrensninger.

Ledende videobrikkeprodusenter NVIDIA og AMD presenterte plattformer for parallell databehandling – henholdsvis CUDA og CTM. Skjermkort har nå maskinvarestøtte for direkte tilgang til dataressurser. CUDA er en utvidelse av programmeringsspråket C. CTM er mer som en virtuell maskin som kun kjører assembly-kode. Begge plattformene fjernet begrensningene til tidligere versjoner av GPGPU, som brukte den tradisjonelle grafikkpipen, og selvfølgelig Direct3D- og Open GL-grafikkbibliotekene.

OpenGL er mer bærbar og også allsidig på grunn av sin åpen kildekode. Men det vil ikke tillate at den samme koden brukes på brikker fra forskjellige produsenter. Slike metoder har mange ulemper, de er ikke praktiske og har liten fleksibilitet. De lar deg heller ikke bruke de spesifikke egenskapene til enkelte skjermkort, for eksempel raskt delt minne.

Dette er akkurat det som skjedde med NVIDIA for å slippe CUDA-plattformen - et C-lignende programmeringsspråk, utstyrt med egen kompilator, og har også biblioteker for GPU-databehandling. Å skrive god kode for videobrikker er ikke lett, men CUDA gir deg mer kontroll over skjermkortmaskinvaren. CUDA dukket opp med skjermkort av 8-serien. CUDA versjon 2.0 dukket opp, som støtter dobbelpresisjonsberegninger i 32- og 64-biters Windows, Linux, MacOS X.

4. Forskjellen mellom CPU og GPU

Økningen i klokkehastighet ble avsluttet på grunn av høyt strømforbruk. Økningen i ytelse oppstår på grunn av en økning i antall kjerner på en brikke. Foreløpig selges prosessorer med opptil åtte kjerner og et antall tråder på opptil 16 for hjemmebrukere.I slike prosessorer opererer hver kjerne separat.

Spesielle vektorfunksjoner (SSE-instruksjoner) for 4-komponent (enkelpresisjon flytepunkt) og 2-komponent (dobbel presisjon) vektorer dukket opp i generell prosessorer på grunn av de høye kravene til grafikkapplikasjoner. Derfor er bruken av GPU mer lønnsomt, fordi De ble opprinnelig designet for slike oppgaver.

I NVIDIA-brikker er hovedenheten en multiprosessor med 8-10 kjerner og rundt hundre ALUer med flere tusen registre og stort delt minne. Videokortet har globalt minne tilgjengelig fra alle multiprosessorer, lokalt minne i hver multiprosessor, og har også minne for konstanter.

I GPUer er kjernene SIMD-kjerner (single instruction stream, multiple data stream). Disse kjernene utfører de samme instruksjonene på samme tid. Dette er stilen for programmering av grafiske algoritmer. Den er spesifikk, men lar deg øke antall beregningsenheter på grunn av sin enkelhet.

De viktigste forskjellene mellom arkitekturene (GPU og CPU): CPU-kjerner utfører en tråd med sekvensielle instruksjoner med maksimal ytelse, GPU utfører et stort antall parallelle instruksjonstråder. Generelle prosessorer er rettet mot å oppnå høy ytelse av en enkelt instruksjonstråd, behandle tall med og uten flytende komma. Minnetilgang er tilfeldig.

Policyen til CPU-utviklere er å få flere instruksjoner utført parallelt for å øke ytelsen. Derfor, fra og med Intel Pentium-prosessorer, dukket det opp superskalær utførelsesteknologi, som representerer utførelse av 2 instruksjoner per klokkesyklus, og Pentium Pro-prosessoren ble preget av utførelse av instruksjoner.

Videobrikker har en enklere operasjon og er parallellisert fra starten. Brikken tar en gruppe polygoner, alle nødvendige operasjoner og produserer piksler. Polygoner og piksler behandles uavhengig av hverandre. Det er derfor GPUen har et så stort antall prosessorer. Moderne GPUer er også i stand til å utføre mer enn én instruksjon per klokkesyklus.

En annen forskjell mellom en CPU og en GPU: prinsippet om minnetilgang. I GPU er det sammenhengende og forutsigbart, fordi hvis teksturer ble talt, betyr det at etter en tid vil overgangen til naboteksturer komme. Derfor er minneorganisasjonen til skjermkortet og sentralprosessoren forskjellig. Og av denne grunn trenger ikke videobrikken et stort hurtigbufferminne, og teksturer krever bare omtrent 128-256 kB.

Å jobbe med hukommelse er også annerledes. CPUer har innebygde minnekontrollere, GPUer har vanligvis flere av dem, opptil åtte 64-bits kanaler. I tillegg brukes veldig raskt minne, derfor er minnebåndbredden høyere, noe som er et pluss for parallelle beregninger som opererer med enorme datastrømmer.

I en CPU brukes et stort antall transistorer på kommandobuffere, prediksjon av maskinvaregrener og enorme mengder cache-minne. Alle disse blokkene er nødvendige for å få fart på de få kommandostrømmene. I GPU-er går transistorer til arrays av utførelsesenheter, lite delt minne, flytkontrollenheter og minnekontrollere. Alt dette fremskynder ikke utførelsen av individuelle tråder, men lar deg behandle et stort antall av dem samtidig.

Buffer. CPU-en bruker hurtigbufferen til å redusere minnetilgangsforsinkelse, noe som resulterer i økt ytelse. GPUen bruker cache for å øke gjennomstrømningen. CPU-en reduserer minnetilgangsforsinkelse gjennom en stor hurtigbuffer og kodegrenprediksjon. Disse maskinvaredelene er store på brikken, og bruker derfor mye strøm. GPUer løser problemet med minnetilgangsforsinkelse på en annen måte: å kjøre tusenvis av tråder samtidig. Når en tråd venter på data, utfører en annen tråd beregningene uten å vente eller forsinke.

Generelt kan vi trekke følgende konklusjon: videobrikker er designet for parallelle beregninger med en stor mengde data og et stort antall aritmetiske operasjoner.

5. Første bruk av beregninger på grafikkakseleratorer

Historien om å bruke brikker til matematiske beregninger begynte for lenge siden. De aller første forsøkene var primitive og brukte noen funksjoner fra Z-buffring og rasterisering. Men med fremveksten av shaders begynte akselerasjonen. I 2003 SIGGRAPH har en ny seksjon for databehandling, og den mottok GPGPU.

BrookGPU. Velkjent kompilator av programmeringsspråket Brook. Strømmer. Den ble spesielt designet for GPU-databehandling. Utviklerne brukte API: Direct3D eller OpenGL. Dette begrenset bruken av GPUer betydelig, fordi Shaders og teksturer ble brukt i 3D-grafikk, og spesialister på parallellprogrammering er ikke pålagt å kunne noe. De bruker nåværende tråder og kjerner. Brook kunne hjelpe litt med denne oppgaven. Utvidelser til C-språket hjalp til med å skjule 3D API for programmerere og gi videobrikken som en parallell koprosessor. Kompilatoren kompilerte koden og koblet den til DirectX-, OpenGL- eller x86-biblioteket.

6. Bruksområder for parallellberegninger på grafiske akseleratorer

Her er gjennomsnittstallene for økningen i dataytelse oppnådd av forskere over hele verden. Når du bytter til en GPU, er ytelsesøkningen i gjennomsnitt 5-30 ganger, og i noen eksempler når den opp til 100 ganger (vanligvis er dette kode som er uegnet for beregninger med SEE.

Her er noen eksempler på akselerasjoner:

· Fluorescensmikroskopi - 12 ganger;

· Molekylær dynamikk - 8-16 ganger;

· Elektrostatikk (direkte og multi-level Coulomb summering) - 40-120 ganger og 7 ganger.

kjerneprosessorgrafikk

Konklusjon

I det abstrakte var vi i stand til å vurdere parallell databehandling på flerkjerneprosessorer, samt CUDA- og CTM-teknologier. Forskjellen mellom CPU og GPU ble diskutert, hva som var vanskelighetene med å bruke skjermkort i parallell databehandling uten CUDA-teknologi, og bruksområder ble vurdert.

Sammendraget vurderte ikke bruken av parallell databehandling i sentrale prosessorer med en integrert videokjerne. Dette er prosessorer i AMD A-serien (AMD A10, AMD A8, AMD A6, AMD A4) og prosessorer i Intel i3/i5/i7-serien med innebygd HD Graphics-videokjerne.

Liste over brukt litteratur

1. Nettstedet ixbt.com, eier av Byrds Research and Publishing, Ltd

2. Nettsted wikipedia.org, eier Wikimedia Foundation

3. Nettstedet nvidia.ru, eier av NVIDIA-selskapet

Skrevet på Allbest.ru

...

Lignende dokumenter

    Batchmetoden som hovedmetoden for å utføre kommunikasjonsoperasjoner, dens innhold og krav. Estimering av kompleksiteten til en dataoverføringsoperasjon mellom to klyngenoder. Stadier av utvikling av parallelle algoritmer (parallellisering).

    presentasjon, lagt til 02.10.2014

    Introduksjon til historien om utviklingen av multiprosessorsystemer og parallell databehandling. Personlige datamaskiner som vanlige enkeltprosessorsystemer på Intel- eller AMD-plattformen som kjører enkeltbrukeroperativsystemer.

    presentasjon, lagt til 22.02.2016

    Klassifisering av parallelle datasystemer. Viktige konsepter og komponenter i parallelle datamaskiner, deres komponenter. Funksjoner av klassifiseringene til Hender, Hockney, Flynn, Shore. Systemer med delt og lokalt minne. Metoder for å dele hukommelse.

    kursarbeid, lagt til 18.07.2012

    Matematisk grunnlag for parallellberegning. Egenskaper for Parallel Computing Toolbox. Utvikling av parallelle applikasjoner i Matlab. Eksempler på programmering av parallelle oppgaver. Beregning av et bestemt integral. Seriell og parallell multiplikasjon.

    kursarbeid, lagt til 15.12.2010

    Utvikling av OS konsepter og muligheter. Parallelle datasystemer og funksjoner i operativsystemet deres. Symmetriske og asymmetriske multiprosessorsystemer. Typer servere i klient-server-systemer. OS for cloud computing. Cluster datasystemer.

    foredrag, lagt til 24.01.2014

    Teknologi for utvikling av parallelle programmer for multiprosessor datasystemer med delt minne. Syntaks, semantikk og struktur av OpenMP-modellen: direktiver, prosedyrer og miljøvariabler. Parallellisering av data og operasjoner, synkronisering.

    presentasjon, lagt til 02.10.2014

    Parallelle databehandlingssystemer, deres generelle egenskaper og funksjonelle egenskaper, vurdering av evner, intern struktur og sammenkobling av elementer, typer: enkelt- og multiprosessor. Parallell form av algoritmen, dens representasjon og implementering.

    test, lagt til 06.02.2014

    Fordeler med multiprosessorsystemer. Opprettelse av et program som implementerer driften av et multiprosessorsystem med delt minne for å behandle forskjellige antall forespørsler, samt forskjellige antall prosessorer. Modeller av beregninger på vektor- og matrisedatamaskiner.

    kursarbeid, lagt til 21.06.2013

    Abstrakte modeller og metoder for parallell databehandling, tillatte beregningsfeil. Konseptet med en parallell prosess, deres synkroniserings- og parallelliseringsgranuler, definisjonen av Amdahls lov. Arkitektur av multiprosessor datasystemer.

    avhandling, lagt til 09.09.2010

    Databehandlingssystemer med én prosessor kan ikke takle å løse militære anvendte problemer i sanntid, og derfor brukes multiprosessordatasystemer (MCS) for å øke ytelsen til militære datasystemer.

Merknad: Hva får utdanning til å endre seg, parallell databehandling i skjæringspunktet mellom disipliner, sekvensiell databehandling maskerer utviklingsproblemer, behovet for å lære hvordan man løser problemer effektivt, årsaken til mange vanskeligheter er uvitenhet om strukturen til algoritmer, mulige måter å endre situasjonen på

Det er kjent at det å mestregsteknologi, spesielt av unge spesialister, kommer med store vanskeligheter. Dette skyldes etter vår mening at kjennskap til parallellberegning, samt utdanning på dette området generelt, ikke begynner med der man bør begynne. I tillegg er det du trenger å begynne med ikke dekket i noen kurs i det hele tatt.

Evnen til raskt å løse problemer ved hjelp av datateknologi med parallell arkitektur tvinger brukere til å endre hele sin vanlige interaksjonsstil med datamaskiner. Sammenlignet for eksempel med personlige datamaskiner og arbeidsstasjoner, endres nesten alt: andre programmeringsspråk brukes, de fleste algoritmer er modifisert, brukere er pålagt å gi en rekke ikke-standardiserte og vanskelig tilgjengelige egenskaper for oppgavene som skal løses, grensesnittet slutter å være vennlig, etc. Et viktig faktum er at unnlatelse av å fullt ut ta hensyn til nye driftsforhold kan redusere effektiviteten ved bruk av nytt og dessuten ganske dyrt utstyr betydelig.

Det skal bemerkes at den generelle karakteren av vanskelighetene som følger med utviklingen av parallell databehandling ser generelt ut som den var i tiden med sekvensiell databehandling. Bare for parallell databehandling vises alle vanskelighetene i en mer akutt form. Mye på grunn av den større kompleksiteten til fagområde. Men, kanskje, hovedsakelig på grunn av det faktum at ved begynnelsen av den aktive introduksjonen av parallelle arkitekturdatasystemer i praksisen med å løse store anvendte problemer, hadde det nødvendige teoretiske grunnlaget ikke blitt bygget og det matematiske forskningsapparatet ikke blitt utviklet. Til slutt, på grunn av dette, viste hele utdanningssyklusen innen parallell databehandling seg å være uforberedt i tide, hvis ekko fortsatt er tydelige i dag. Derav mangelen på forståelse av de mange vanskelighetene med å mestre moderne datateknologi, hull i opplæringen av de nødvendige spesialistene og mye mer.

Utdanning innen parallell databehandling er basert på tre disipliner: datasystemarkitektur, programmering og beregningsmatematikk. Hvis du nøye analyserer innholdet i de relevante kursene, vil du uunngåelig komme til den konklusjon at ikke bare individuelt, men til og med alle sammen, sikrer de for øyeblikket ikke oppnåelsen av hovedmålet. tilpasset mål - å lære effektivt løse store problemer på store datasystemer med parallell arkitektur. Disse kursene gir selvfølgelig mye nyttig og nødvendig informasjon. Imidlertid er mye som må være kjent i henhold til det moderne synet på parallell databehandling ikke gitt i dem. Spesielt dette skyldes det faktum at en rekke av de viktigste og til og med grunnleggende fakta, metoder og teknologier for å løse store problemer på store systemer oppsto som et resultat av forskning i skjæringspunktet mellom flere fagområder. Slike resultater passer ikke inn i rammen av tradisjonelle disipliner. Derfor, som en konsekvens, viser det seg at informasjonen som presenteres i de relevante kursene er utilstrekkelig for dannelsen hele systemet kunnskap fokusert på kompetent konstruksjon av parallelle databehandlingsprosesser.

Alle utdanningsløp som på en eller annen måte er knyttet til datateknologi eller bruken av den kan deles inn i to grupper. Den første gruppen inneholder grunnleggende informasjon, den andre - spesiell informasjon. Grunnleggende informasjon er universell og er dårlig klassifisert etter type datateknologi. De ble dannet på grunnlag av kunnskap om sekvensielle maskiner og sekvensielle beregninger og endres lite over tid. Som en del av programmeringskurset begynner grunnleggende informasjon å leses fra første eller andre semester, som en del av kurset numerisk metode fra cirka tredje semester. Spesielle kurs, inkludert de som er relatert til parallelle arkitekturdatasystemer, begynner å bli undervist ganske sent. Som regel ikke tidligere enn syvende eller til og med niende semester.

Ved første øyekast ser alt logisk ut: først gis grunnleggende informasjon, deretter spesiell informasjon. Men i praksis viser inndelingen av informasjon i grunnleggende og spesiell seg å være svært betinget, siden bare følgende er viktig: er det mulig å få den nødvendige informasjonen til rett tid eller er det ingen slik mulighet og hva er settet informasjon som tilbys for studier.

Utviklingen av beregningsmatematikk har en lang historie. Men den raskeste utviklingen er knyttet til elektroniske datamaskiner. Disse maskinene oppsto som et verktøy for å utføre påfølgende beregninger. Mens de utviklet seg raskt, forble de i hovedsak konsistente i flere tiår. For sekvensielle maskiner begynte de å lage ganske tidlig maskinuavhengig programmerings språk. For matematikere og ga fremveksten av slike språk et attraktivt perspektiv. Det var ikke nødvendig å fordype seg i utformingen av datamaskiner, siden programmeringsspråk i hovedsak skilte seg lite fra språket til matematiske beskrivelser. Hastigheten for implementering av algoritmer på sekvensielle maskiner ble hovedsakelig bestemt av antall utførte operasjoner og var nesten uavhengig av hvordan selve algoritmene var internt strukturert. Derfor, i utviklingen av algoritmer, ble de viktigste objektive funksjonene til kvaliteten deres åpenbare - å minimere antall utførte operasjoner og motstand mot påvirkning av avrundingsfeil. Ingen annen informasjon om algoritmer var rett og slett nødvendig for å effektivt løse problemer ved hjelp av sekvensiell teknologi.

Alt dette i mange år bestemte hovedretningen for utvikling ikke bare av numeriske metoder, men også for all beregningsmatematikk. På bakgrunn av utilstrekkelig oppmerksomhet til utviklingen av datateknologi, la ikke matematikere merke til en viktig omstendighet i tide: kvantitative endringer i teknologien blir allerede til så kvalitative at kommunikasjon med den ved hjelp av sekvensielle språk snart skulle bli umulig. Dette har ført til et alvorlig gap mellom eksisterende kunnskap om algoritmer og kunnskapen som trengs for raskt å løse problemer med den nyeste datateknologien. Det resulterende gapet ligger til grunn for mange av vanskelighetene i den praktiske utviklingen av moderne datasystemer med parallell arkitektur.

Nå har dataverdenen, i hvert fall den store dataverdenen, endret seg radikalt. Det ble parallelt. På datasystemer med parallell arkitektur avhenger tiden det tar å løse problemer fundamentalt av hva den interne strukturen til algoritmen er og i hvilken rekkefølge operasjonene utføres. Muligheten for akselerert implementering på parallelle systemer oppnås på grunn av det faktum at de har et tilstrekkelig stort antall funksjonelle enheter som samtidig kan utføre noen operasjoner av algoritmen. Men for å bruke denne muligheten, er det nødvendig å få ny informasjon om strukturen til algoritmen på nivået av forbindelser mellom individuelle operasjoner. Dessuten må denne informasjonen samsvare med informasjon om arkitekturen til datasystemet.

Nesten ingenting sies i utdanningskurs om felles analyse av systemarkitektur og algoritmestruktur. Mens arkitekturer av datasystemer og parallell programmering undervises i det minste i spesielle kurs, er diskusjon av strukturene til algoritmer på nivå med individuelle operasjoner foreløpig ikke inkludert i noen pedagogiske disipliner. Og dette til tross for at strukturene til algoritmer har vært diskutert i den vitenskapelige litteraturen i flere tiår, og praksisen med å bruke datateknologi for parallell arkitektur ikke har vært i en mye kortere periode. Naturligvis dukket spørsmålet opp om hva du skulle gjøre videre. Svaret på dette er allerede gitt tidligere, men det er nyttig å gjenta det.

Frem til nå har beregningsmatematikere blitt lært hvordan de løser problemer matematisk riktig. Nå må vi også lære hvordan vi løser problemer effektivt ved hjelp av moderne datateknologi.

Hvilken informasjon innen algoritmestruktur du trenger å vite i tillegg ble diskutert i de gitte forelesningene. Basert på dette materialet kan det utvikles ulike programmer for modernisering av utdanningsløp. av hensyn til parallell databehandling. Den mest effektive moderniseringen innebærer avtalt endringer på flere kurs. Et av programmene, designet for å trene høyt kvalifiserte spesialister til å løse store problemer på store systemer, kan se slik ut:

  • lese tre eller fire forelesninger "Introduksjon til parallellberegning" i de første kursene;
  • innføring i grunnleggende sykluser i matematikk og programmering av grunnleggende informasjon om parallellberegning;
  • en betydelig omstrukturering av serien med forelesninger om numeriske metoder med en obligatorisk beskrivelse av informasjonsstrukturen til hver algoritme;
  • organisere en workshop om parallell databehandling;
  • lese et spesialkurs " Parallell struktur algoritmer";
  • lese et spesialkurs "Parallell Computing".

Dette programmet er på en viss måte det maksimale. Det er imidlertid veldig ekte. Selvfølgelig kan det ikke implementeres fullt ut på alle universiteter. Men på grunnlag av det kan hvert enkelt universitet formulere sitt eget utdanningsprogram innen datavitenskap.

Fra de to første punktene kan enten ett av dem, eller begge samtidig, introduseres i utdanningssyklusen. Det er bare viktig at studenten så snart som mulig Jeg lærte at det er andre måter å organisere dataprosesser på, og ikke bare sekvensiell utførelse "operasjon for operasjon", at den kraftigste moderne datateknologien er bygget på disse andre metodene, at bare med slik teknologi er det mulig å løse store industrielle og vitenskapelige problemer osv. Det er først og fremst viktig å trekke elevenes oppmerksomhet så tidlig som mulig til behovet for en kritisk holdning til filosofien om sekvensiell databehandling. Det er tross alt denne filosofien de må forholde seg til gjennom hele utdanningen, både på skolen og på universitetet. Og det er nettopp denne filosofien som hindrer forståelsen av funksjonene ved å jobbe på datamaskiner med parallell arkitektur.

Det er ganske hensiktsmessig å inkludere grunnleggende informasjon om parallell databehandling i et programmeringskurs. I den kan du diskutere den enkleste modellen parallellt datasystem, snakk om parallelle prosesser og deres egenskaper. Her er det nyttig å introdusere en abstrakt form for beskrivelse av beregningsalgoritmer. Dessuten er det slett ikke nødvendig å gi spesifikt innhold. Det er bedre å snakke om dette senere når du studerer numeriske metoder. Vi kan begynne å snakke om parallelle former for algoritmer og deres bruk. All informasjon om parallellberegning kan etter vår mening presenteres i et programmeringskurs i to eller tre forelesninger. Et godt testområde for å demonstrere parallellisme i algoritmer er et lineært algebrakurs. Matriseoperasjoner og Gauss-metoden for å løse systemer med lineære algebraiske ligninger dukker opp ganske tidlig i den. Ved å bruke de riktige algoritmene, til og med "på fingrene", kan du demonstrere parallellisme av beregninger, raske algoritmer og mye mer. Diskusjon av ny informasjon vil ikke kreve mer enn én forelesning totalt.

Du bør ikke overbelaste din første introduksjon til parallell databehandling med mange detaljer og seriøse resultater. Hovedmålet med denne fasen er kun å vekke interesse for dette temaet. Det er nok å gi en generell idé om beregningsmessig parallellisme, parallelle former, algoritmegrafer og egenskaper ved beregningsprosesser. Hvis all den første informasjonen er kombinert i en enkelt serie "Introduksjon til parallell databehandling", kan den dekkes i tre eller fire forelesninger. Men la oss igjen understreke at det er nødvendig å bringe denne informasjonen til studentene så tidlig som mulig.

Materialene i disse forelesningene demonstrerer på en overbevisende måte hvor viktig god kunnskap om algoritmegrafer og deres parallelle former er for å forstå problemene man må møte når man løser problemer på moderne parallellarkitektur-datasystemer. Det er mest naturlig å inkludere informasjon om dette i kurs om beregningsmatematikk. Hovedargumentet for en slik løsning er knyttet til at informasjonsstrukturen til algoritmene er beskrevet i den samme indekssystemer der presentasjonen og numeriske metoder finner sted. I det store og hele er alt som må legges til det eksisterende kurset om numeriske metoder informasjon om algoritmegrafer, sett med skanninger for dem og teknologien for å bruke alt dette. Å utarbeide oppdaterte kurs krever selvfølgelig litt arbeid. Men det er slett ikke nødvendig å diskutere strukturene til algoritmer i sin helhet. Det er nok å gjøre dette bare for deres datakjerner. Konseptet med algoritmegrafer og teknologi bør mest sannsynlig presenteres helt i begynnelsen av kurset. Det er imidlertid tilrådelig å gi en graf og utviklinger for hver algoritme. I tillegg til det ovennevnte, merker vi at de samme numeriske metodene leses uten endring i mange år, og informasjon om deres strukturer må utarbeides bare én gang. Og denne informasjonen vil helt sikkert bli brukt mange ganger, og på en rekke områder.

En av de vanskeligste teknisk og minst utviklet fra et metodisk synspunkt er spørsmålet om å organisere en workshop om parallell databehandling. For å utføre det må du selvfølgelig ha parallell databehandlingsteknologi. Men på mange universiteter har denne teknologien vært tilgjengelig i lang tid, og det er fortsatt ingen endelig mening om hvordan verkstedet skal være.

Et av de åpenbare målene med workshopen ligger på overflaten. Datasystemer med parallell arkitektur er laget for å løse store problemer. Derfor, under workshopen, må du i det minste til en viss grad lære hvordan du løser slike problemer. Alt ser ut til å være klart. I et generelt programmeringskurs eller i noen spesialkurs gis kunnskap om spesifikke språk eller parallelle programmeringssystemer. Under workshopen gis det konkrete oppgaver. Programmer kompileres, kjøres på et datasystem, og resultatene sammenlignes med en standard. Men selv en så enkel ordning har flaskehalser. Faktisk, hva anses som et resultat? Når du løser store problemer på store systemer, er hovedvanskeligheten ikke så mye å oppnå matematisk riktig resultat hvor mye prestasjon ønsket akselerasjonsnivå. Dette betyr at du under den praktiske opplæringen også må lære hvordan du kan evaluere effektiviteten til kompilerte programmer.

Hvis et bestemt program ikke viser de nødvendige ytelsesegenskapene, oppstår spørsmålet om ytterligere handlinger. I denne situasjonen må du nesten alltid begynne en mer detaljert studie av strukturen til algoritmene. Kanskje er det studiet av strukturen til algoritmer som bør bli nøkkelelementet i verkstedet. Det vil være en god hjelp til å introdusere strukturen til algoritmer i moderniserte kurs om numeriske metoder. Men det er også sterkere argumenter for å bli mer kjent med strukturen til algoritmer.

Ett argument har med aktuelle problemstillinger å gjøre. Nylig har ulike multiprosessorsystemer med distribuert minne blitt mye brukt i databehandling. Disse inkluderer ikke bare klynger, men også heterogene nettverk av datamaskiner, nettverk av datamaskiner koblet til via Internett, osv. I alle slike systemer er flaskehalsen informasjonsutveksling mellom prosessorer. For å fungere effektivt, er det nødvendig at hver prosessor utfører ganske mange operasjoner og utveksler relativt små biter av data med minnet til andre prosessorer. Vi har allerede bemerket i forelesninger at for å sikre en slik beregningsmodus, er det nok å kjenne til algoritmegrafen og minst to uavhengige utviklinger. Du må med andre ord kjenne strukturen til algoritmene.

Et annet argument er knyttet til mulige utsikter for utvikling av datateknologi. Hastigheten på å løse store problemer må økes i dag og vil helt sikkert måtte økes i fremtiden. Som regel er hovedhåpene knyttet til opprettelsen av raskere hastigheter basert på ulike teknologiske prestasjoner. universell systemer Men det er mulig å øke hastigheten på datateknologi på grunn av dens spesialiseringer. Bruken av spesielle prosessorer som utfører svært rask implementering av raske Fourier-transformasjonsalgoritmer, signalbehandling, matriseoperasjoner, etc. har lenge vært praktisert. La oss nå huske hypotesen om typiske strukturer. Hvis det er riktig, vil det i spesifikke applikasjonsområder være mulig å identifisere de mest brukte algoritmene og bygge spesielle prosessorer for dem. Dette åpner opp for å lage spesialiserte datasystemer for rask og ultrarask løsning av problemer fra en gitt fagområde.

Den største vanskeligheten med å introdusere oppgaver knyttet til studiet av strukturen til algoritmer i verkstedet er den nåværende mangelen på tilgjengelig og brukervennlig programvare for å konstruere algoritmegrafer og utføre ulike studier basert på dem. I hovedsak er det bare ett system som implementerer slike funksjoner. Dette er et V-Ray-system utviklet ved Research Computing Center ved Moscow State University. Det gjør det mulig for ulike klasser av programmer å bygge grafer av algoritmer og studere deres parallelle struktur. V-Ray-systemet er implementert på en personlig datamaskin og er uavhengig av måldatamaskinen. Den siste omstendigheten er ekstremt viktig for å organisere en workshop, siden hyppig tilgang til store datasystemer med små oppgaver ikke er veldig realistisk selv for universiteter med godt teknisk utstyr. På personlige datamaskiner er tiden for å mestre verkstedets oppgaver praktisk talt ubegrenset. Foreløpig representerer V-Ray et komplekst forskningssystem. Ikke alle funksjonene er nødvendige for å organisere en workshop. Over tid vil V-Ray-systemet bli tilgjengelig for utbredt bruk. Informasjon om den og dens funksjoner kan fås

Anmeldelse