Intel udvikler nyt, parallelt C-programmeringssprog

Intel vil effektivisere parallel programmering ved hjæp af programmeringssproget Ct, som processorfirmaet har udviklet som en overbygning til C++.

Det hjælper ikke meget med processorer, der er fyldt til randen med kerner, hvis softwaren ikke udnytter muligheden for flere processer, der kører parallelt.

Derfor startede Intel for et par år siden et forskningsprojekt for at udvikle et parallelt programmeringssprog, der effektiviserer og simplificerer udviklingen af programmer til processorer og grafikkort med mange processorkerner.

Nu er forskningsprojektet slut, og der er oven i købet kommet et produkt ud af det. Den første offentlige betaudgave ser dagens lys mod årets slutning, mens den endelige version kommer på markedet til næste år.

Det fremgik af en briefing, som Intel afholdt tidligere på ugen i Mountain View i Californien, som Version2 var med til.

Ct er et programmeringssprog, der er baseret på C++, hvilket også fremgår af C'et i navnet. T'et står for ?throughput?, hvilket hentyder til bedre udnyttelse af processorkernerne.

Ct er en overbygning til C++, der fungerer som en præprocessor, så Ct kan altså anvendes sammen med en vilkårlig C-compiler.

Intel har også sørget for, at de mest almindelige operativsystemer er understøttet, hvilket vil sige diverse Windows-versioner i både 32- og 64-bit-udgaver samt Linux og Mac OS.

Selvom Intel har udviklet med firmaets egne processorer i tankerne, er der intet i vejen for, at Ct kan anvendes sammen med flerkerneprocessorer fra AMD.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Kommentarer (7)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
#2 Ville Witt

Til grin at opfinde den dybe tallerken igen... Ada har haft templates siden langt før C++, exceptions, garbagecollection(valgfri), in-language concurrency, og ordentligt type system hvor man slipper for meget af 16/32/64(/128). Java forsøger netop at kopiere Adas model for concurrency.

Og så har mange universiteter, stater og industrien lavet det sammen så det passer til de fleste. I stedet for konstant at lave nye sprog valgte de at se dette faktum i øjnene og så lavede de et sporg der var omfattende fra starten, men hvor man slap for konstant at lave et version-bump.

Vi havde iøvrigt en compilerproducent i lyngby - helt science fiction er det ikke. Sproget bruges til kritiske systemer - også i Danmark! Og til alle de ikke-programmører der lytter med: Ada er læse venligt så netop i - domænespecialisterne - kan se koden og undersøge at computeren gør som den skal i den rigtige verden. Tror du mig ikke? Undersøg sagen selv... Google ved faktisk ret meget om sagen...

btw, sproget er en ISO standard - og en standard man kan se UDEN at skulle betale store summer til ISO. Tak US militær, godt i betalte for denne detalje. Og tak USA fordi i betalte en open source gratis og fri compiler.

Nåh, tilbage til Ada og LEGO NXT...

  • 0
  • 0
#3 Jesper Louis Andersen

Der er ikke tale om en genopfindelse af den dybe tallerken her. Ada har haft fokus på concurrency, hvilket ikke er det samme fokus som Intels Ct hvor parallellisme er vigtigst. De to ting er ikke de samme.

I Ada er concurrency-primitiverne Threads, shared resources og semaforlåse. I Ct kan du erklære at eksempeltvist et array er parallelt, så en løkke der traverserer arrayet kan splittes ud på flere cores. Hvis der er tale om en genopfindelse er det nok snarere OpenMP som er genopfundet her.

Iøvrigt er threads og shared resources næppe en holdbar concurrency-model i længden. Hele ideen om delt hukommelse mellem CPUer spår jeg kommer under pres indenfor de næste 5-10 år. Lige nu er vi i stand til at gemme de fleste af problemerne bag MESI og cache, men det varer ikke ved.

  • 0
  • 0
#4 Deleted User

Hele ideen om delt hukommelse mellem CPUer spår jeg kommer under pres indenfor de næste 5-10 år.

Hardwaremæssigt, er delt hukommelse også besværligt. Skal der være n-way access, er det dyrt i areal - og alternativet er at flere deles om samme addressebus, og så kan det give en flaskehals. Delt hukommelse, mellem CPU'er, er vel på en måde en "opfindelse" af von-Neumanns flaskehals, for parallelisme.

Sædvanligvis, er den bedste måde at beskrive programmer på, at bruge "fifo'er" mellem processerne, ligesom programmeringssprog som Erlang.

I ganske få tilfælde, hvor flere computere, eller personer, skal have adgang til en data, kan dog komme på tale med delt hukommelse, der naturligvis skal beskyttes med lås efter alle kunstens regler.

Umiddelbart lyder en "overbygning" ovenpå C++, som en hurtig løsning, men ikke en fremtidsrettet løsning. Jeg tror, at man skal udvikle sprog, der er egnet til deterministisk, parallel kodning, og som har indbygget parallelisering af sekventiel kode, da sekventiel kode, ofte er den mest overskuelige form for repræsentation og kodning af et problem. Kun opgaver, der i sagens natur er parallele, bør kodes parallelt. Ellers, hører opgaven under automatik, og højst at hjælpe automatikken med at parallelisere den sekventielle beskrivelse. Overskueligheden, er altid den vigtigste.

  • 0
  • 0
#5 Torben Mogensen Blogger

Umiddelbart lyder en "overbygning" ovenpå C++, som en hurtig løsning, men ikke en fremtidsrettet løsning. Jeg tror, at man skal udvikle sprog, der er egnet til deterministisk, parallel kodning, og som har indbygget parallelisering af sekventiel kode, da sekventiel kode, ofte er den mest overskuelige form for repræsentation og kodning af et problem. Kun opgaver, der i sagens natur er parallele, bør kodes parallelt. Ellers, hører opgaven under automatik, og højst at hjælpe automatikken med at parallelisere den sekventielle beskrivelse. Overskueligheden, er altid den vigtigste.

Jeg er enig i, at en variant af C eller C++ ikke er en fremtidssikret løsning, og at delt lager ikke skalerer. Men jeg er ikke enig i, at man skal lade oversætteren parallelisere sekventiel kode -- det gør performance for følsomt overfor smådetaljer i kodningen. F.eks. er det meget almindeligt i paralleliserende oversættere, at en meget lille ændring i koden betyder, at den bliver oversat sekventielt i stedet for parallelt.

Det er bedre at programmere parallelt og lade oversætteren (eller køretidssystemet) se, om det kan betale sig at køre det lokalt, eller om det skal fordeles mellem flere processorer.

Det er ikke egentligt mere besværligt at programmere parallelt end sekventielt, det virker kun sådan for folk, som har fået indlært dårlige vaner såsom brug af eksplicit lagerlayout eller objekter med felter, der opdateres med sideeffekter. Et skift til en hel anderledes programmeringsstil er altid svær, men det betdyer ikke, at den nye stil i sig selv er vanskeligere ende den gamle, den er bare mindre velkendt. Det er ligesom at lære kinesisk: Det virker utroligt kompliceret for en europæer, mens kineserne synes det samme om f.eks. engelsk.

  • 0
  • 0
#6 Esben Nielsen

Jeg er uenig med jer: Der er steder hvor "delt hukommelse" er en rigtig god idé.

Én af de steder, hvor man kan bruge det, er regulering af (store) maskiner. Den totale opgave kan deles op i små-opgaver, hvor hver små-opgave kræver relativt meget input data, som er delvis fælles med andre del-opgaver, og giver relativt få output data. Dvs. man har mange læsninger og få skrivninger. Delt hukommelse giver mulighed for altid at læse den seneste input værdi, hvorimod fifo princippet er meget besværligt, da man "manuelt" skal route og behandle alt data hen til forbrugerne. Delt hukommelse vil ofte bliver emuleret ovenpå IP, da CPU'erne er fysisk adskilt; men det ville være meget nemmere at have hardware, som direkte understøtter det.

Generelt, hvis ens parelle opgaver skal læse megen fælles data, er "delt hukommelse" en god ide set fra applikationsudvikleren. Hvordan, det er lavet nedenunder (i hardware eller software), må afhænge af situationen. "Delt hukommelse" er også ment mere abstrakt en blot et fladt adresse område.

  • 0
  • 0
#7 Deleted User

Når et program beskrives, er fifoprincippet bedre end delt hukommelse af mange årsager - det lader sig nemt analysere, der er ikke problemer med "låsning", og det er deterministisk!

At det i nogle tilfælde, måske virker mere effektivt, at have en fælles ROM, som data hentes fra, betyder ikke noget. Typisk, kan du analysere dig ud af sådanne problemer. Forestiller vi os et program, hvor at en stor datablok, overføres til en fifo (de data, der lægges ind i en fifo, kan i princippet være såvel konstante, som objekter, eller store arrays), så kan kompileren relativ nemt i stedet overføre en pointer, til hvor data befinder sig. Ofte, er en fordel, at konstante kopieres ud til hver enkelt process, således at pointeren peger til data for den pågældende process. Det er ikke noget du som sådan behøver at tænke på som programmør.

Problemet er, at mange programmører er for lidt dataloger - og for meget maskinkodehackere. Dette skyldes ikke mindst sprog som C og C++. De er vandt til, at ikke beskrive hvad de ønsker gjort - men hvordan det ønskes gjort. I et godt programmeringssprog, er det væsentlige at beskrive hvad du ønsker gjort - og compilerens opgave, kombineret med hardware og OS, er at omsætte dette til et praktisk program. I princippet, bør du ikke som programmør, tænke på hvordan processoren skal gøre skridt for skridt, og hvilken process, som den pågældende opgave skal lægges under - det eneste du skal, er at opskrive opgaven, så overskueligt som muligt. Herefter, tager automatikken over.

Det, som så er kunsten, er at lave et sprog, hvor det beskrives hvad der skal gøres, og ikke hvordan det ønskes gjort - og at denne beskrivelse, også er så maskinoversætbart, at det er praktisk muligt, at opnå et godt resultat. Der findes mange sprog, hvor man angiver problemet abstrakt - men oftest, er de svært oversættebare, eller kræver tunge algorithmer. Andre sprog, havner i den modsatte grøft, hvor at det beskrives detaljeret, hvilken ramcelle, der ønskes anvendt til at gemme et tal.

Jeg mener, at sprog som C, og C++ havner i den sidste grøft - meddens de funktionelle programmeringssprog, i nogle tilfælde havner i den første.

Selve kodning, og omsætning fra en "beskrivelse" af hvad der ønskes gjort, og til den kode der skal køres på computeren, er bedst hvis gøres så vidt muligt at en compiler. Dette giver bedst mulighed for oversættelse til forskellige computerarkitekturer, dybder af parallelisme, osv.

På den anden side, tror jeg sprog som C, C++, Pascal osv. er så "indgroede", at det ikke er sprog vi kommer bort fra. Men, de kan godt laves bedre og pænere. Jeg synes selv bedst om Pascal, og mener C og C++ har mange fejl udfra et datalogisk synspunkt, sammenlignet med Pascal. C, har et udseende, der for mig minder om lavniveau, og assembler. Selvom de fleste tror, at det gør kodningen mere effektivt, er virkeligheden at det lægger en grænse på compilerens formåen, og koden gøres mere ineffektiv. Abstrakte sprog, vil altid tillade bedste oversættelse, fordi de ikke specificerer eksakt, hvordan det skal oversættes. Et lavniveau sprog, "overspecificerer" en opgave, f.eks. kan ske at de indbyggede typer ikke håndterer en 64 bit integer - denne laves så ved at sætte 2 styk 32 bit sammen, og definere hvordan de f.eks. adderes. Dette er mere ineffektivt, end have et abstrakt sprog, hvor opgaven formuleres, og den 64 bit integer beskrives som en talstørrelse, der er et interval fra -n til +n. I det abstrakte sprog, holder man sig fri af den underlæggende arkitektur, der eksempelvis er en 32 bit processor, og derfor findes ikke 32 bit typer, eller 64 bit typer. I stedet, beskrives talstørrelsen, ved at angive interval, som i Pascal. Et sprog, må helst ikke indrage maskinære størrelser og konstante, men skal fungere uanset bitbredder i CPU'en, registrestørrelser osv. og må helst ikke bero på en maskine der deffinerer sådanne "naturkonstante". For så er ikke muligt, at oversætte effektivt til maskinkode. C, er et sprog, der indeholder masser af maskinære typer, der er indspireret af maskinens binære opbygning. Meddens et abstrakt sprog, ikke vil afspejle maskinens opbygning, såsom registres bitbredde, eller addressebussens bitbredde, men i stedet lade programmøren deffinerer de størrelser de har brug for, ved at eksempelvis opskrive interval der bruges for heltal, eller nøjagtighed der bruges for float. Bruges høj nøjagtighed, er det så compilerens opgave, at eventuelt stykke det sammen af flere indstruktioner, for at opnå nøjagtigheden. Bruges lav nøjagtighed, kan den eventuelt mappes ned i eksisterende hardware eller co-processor. Et abstrakt sprog, styres med andre ord fra programmøren, med hensyn til bit og nøjagtighed - og ikke fra "hardwaren", eller deffinerede typer. Et abstrakt sprog, kan eventuelt også rumme typer, der har udeffineret bredde og længde, da det ikke betyder noget for programmørens program, hvor data fysisk er lagt i lager. En programmør, må i princippet ikke have adgang til sådanne "hardwarenære" data. Typer, som arrays, strenge, integers mv. kan derfor have variabel bitbredde, således integers med uendeligt størrelse kan implementeres, strenge, med uendelig størrelse osv. Memory mannegement, er del af sproget.

Som jeg ser det, er det spændende med algorithmer der "behandler" kode. Det kan være at omsætte sekventiel kode, til parallel kode. Eller, at reducere kode bort. Måske kan koden "analyseres" bort. Eller, den kan analyseres, til at køre godt på et antal parallele VLIW maskiner. Måske, skal sproget virke så du opstiller krav til input/output, såsom eksempelvis maksimum forsinkelse fra input til output, og så vil koden selv blive struktureret, paralleliseret, og prioriteret, således data opfyldes og garanteres. Du ønsker måske, at visse data, har større prioritet end andre - såsom at et output "gerne" skal komme hurtigt - her er det måske også muligt at angive, og den vil "kompilere" og parallelisere koden, således den får højere prioritet.

Sprog, som C og C++ er utroligt simple. Det er gamle sprog, som er baseret på, at du mere eller mindre kan opslå C ordrene i et katalog, og få at vide hvordan det oversættes til maskinkode. I nogle tilfælde, er det så forbedret, med lidt "registeroptimering". Men, i det store hele, er de fleste compilere i sine grundtræk utroligt simple. Jeg tror, at vi skal tænke mere på, hvad computeren kan gøre for os - og gå i retning af, at compileren kan gøre mere, og programmøren skal beskæftige sig med opgaven. Programmørens opgave, er ikke at sidde og parallelisere, eller sekventialisere - eller at "mappe" opgaven ind i et antal processorer og kerner. Programmørens opgave, er at beskrive opgaven, og automatikken skal klare omsætning til hardware, og prioritering af koden. Compileren, skal også kunne analysere kode så grundigt, at det ikke er væsentligt om en programmør anvender "i++", i en sætning - eller har den udenfor, bruger +1, eller noget andet. Compilerens opgave, er at "forstå" det indtastede, og at kunne foretage alle nemme omskrivninger automatisk, så man kan koncenterere sig om at kode overskueligt. Derfor, har som sådan ikke nogen gevindst med "i++" eller at bruge "++" i sætninger, for at optimere koden. Det viser kun, at oversætteren er simpel, og ikke indeholder tilstrækkeligt kompileringsteknologi.

Ovenstående, er baggrunden for, at jeg "idiologisk" mener, at en compiler bør stå for paralleliseringen, og at det bør være ligegyldigt, om vi koder sekventielt eller parallelt. Dens algorithmer, skal være gode nok, til at den selv kan løse denne "slaviske" opgave at parallelisere, og jeg tror på, at det vil komme snart.

Når vi beskriver en opgave, er oftest bedst at bruge "fifo" princippet, fordi det bevisteknisk er nogle fordele, f.eks. determinisme, og at der ikke behøves "lås" mv. Men det er normalt også altid muligt, at omskrive denne beskrivelse, til noget der er ligeså effektivt, som hvis der bruges fælles lager - og dette kan gøres med automatik. Bruger vi derimod fælles hukommelse, er et helvede at omskrive det automatisk til at bruge FIFO princippet. Og ofte, er det umuligt. Ofte, medfører det, at koden ikke er deterministisk, og denne manglende determinsme, gør det svært at analysere koden, hvis overhovedet muligt. Compileren, ved ligesom ikke altid, hvad som sker... FIFO princippets determinisme, er med til at gøre koden analyserbar, og tilsvarende er den manglende determinisme, f.eks. ved flere processer der anvender delt hukommelse, med til at gøre koden mindre analyserbar, eller ikke analyserbar inden for endelig tid. Samtidigt, er det som beskrives, oftest en "fejl". Kodes, efter "fifo" princippet, er koden oftest fejlfri (f.eks. erlang).

  • 0
  • 0
Log ind eller Opret konto for at kommentere