CPU:ssa 1000 ydintä, miten koodia?

Seuraa 
Viestejä45973
Liittynyt3.9.2015

Kysymys (C ja ASM) ohjelmoijille.

Nyt kun julkisuudessakin on "isojen tekijöiden toimesta" annettu ohjelmoijille varoituksia, että "varautukaa tuhansiin ytimiin", eli että ohjelmoijien olisi jo nyt alettava varautumaan siihen, että tietokoneissa on jo lähitulevaisuudessa useampia kuin 32 ydintä, ja että nykyiset ohjelmointikäytänöt ovat tällaiselle arkkitehtuurille sopimattomia.

Kysynkin nyt mielipidettä, että miten tähän pitaisi varautua?

Normaalin PHP, ASP, Viaual Basic, Java jne. -ohjelmoijan ei taatusti tarvitse tietää asiasta höykäsen pölähtävää, mutta entä C/C++ koodarit, varsinkin me/te, jotka toteuttavat laitteistotason koodia, sulautettuja järjestelmiä, aikakriittisiä ratkaisuja, monen käyttäjän transaktiojärjestelmiä jne..

Miten esimerkiksi normaalissa C:llä toteutetussa ohjelmistossa olisi otettava huomioon threadit ja prosessit? Perinteisestihän on "thredattu" jos jokin toiminto vie oletettavasti sen verran aikaa, että käyttäjä huomaa toiminnossa viivettä. Tällöin jaetaan prosessi kahteen tai threadataan... Mutta miten on esimerkiksi 1000 ytimen kanssa? Onko koodaajan threadattava jo hyvin pieniä pätkiä koodia, periaatteessa siis jokainen funktio? Vai onko homma yksinkertaisesi niin, että "varoitukset" jylisevät vain kääntäjiä kehittäville tahoille ja "ceetä" kirjoitetaan samaan tapaan kuin ennenkin?

Threadien tekeminenhän vie kuitnkin aikaa ja varsinkin eri threadien ja prosessien hallinta altistaa virheille ja muistivuodoille esimerkiksi sen vuoksi, että jotain "semaphorea" ei ole luotu, jotain kriittistä objektia ei ole lukittu, yritetään lukea jotain mitä toinen threadi ei ole vielä tehnyt, muistissa ei ole tilaa jne...

Nimim. Threadasinko turhaan?

Sivut

Kommentit (31)

Vierailija

Jos näitä 1000 ytimen prossuja oikeasti alkaa putkahtelemaan kuin sieniä sateella, niin uskonpa että Erlang-tyylinen säikeistys alkaa yleistyä.
Erlanghan käyttää vihreitä säikeitä (jotka kuitenkin ajetaan useammalla prosessorilla), joissa yksittäinen säie ei jaa muistia minkään muun säikeen kanssa. Säikeiden välinen kommunikaatio tapahtuu lähettämällä viestejä säikeeltä toiselle.
Virheidenhallinta ei tapahdu säikeessä itsessään, vaan niitä voi ketjuttaa yhteen (jolloin kaikki ketjun säikeet pysähtyvät yhden töpätessä) ja virhetilanteisiin vastaavat erilliset valvontasäikeet.

PS: C/C++:llehan on jo nykyään lukuisia moniajokirjastoja.

MaKo71
Seuraa 
Viestejä1467
Liittynyt15.11.2006

Vaikea tuohon on vastata, jos ei tiedä tuollaisen 1000-ytimisen prosessorin arkkitehtuuria. Voisi olettaa, että tuollaisella ydinmäärällä pyrittäisiin siihen, että pienempiäkin tehtäviä rinnakkaistetaan, jolloin rinnakkaistamisessa ykkösasemassa olisi kääntäjä.

Varmaan PS3:n Cell-prosessorin ohjelmoimisesta voi kaivella vinkkejä tulevasta? Kts. vaikka Cell Programming.

Vierailija
Ilmuri
Jos näitä 1000 ytimen prossuja oikeasti alkaa putkahtelemaan kuin sieniä sateella, niin uskonpa että Erlang-tyylinen säikeistys alkaa yleistyä.
Erlanghan käyttää vihreitä säikeitä (jotka kuitenkin ajetaan useammalla prosessorilla), joissa yksittäinen säie ei jaa muistia minkään muun säikeen kanssa. Säikeiden välinen kommunikaatio tapahtuu lähettämällä viestejä säikeeltä toiselle.
Virheidenhallinta ei tapahdu säikeessä itsessään, vaan niitä voi ketjuttaa yhteen (jolloin kaikki ketjun säikeet pysähtyvät yhden töpätessä) ja virhetilanteisiin vastaavat erilliset valvontasäikeet.

PS: C/C++:llehan on jo nykyään lukuisia moniajokirjastoja.




Jep, mutta silti näin kommentin, jossa sanottiin, että "nykyiset ohjelmointikäytännöt eivät sovellu". Mikä siis soveltuu?

http://www.digitoday.fi/data/2008/07/02 ... 0817616/66

Kosh
Seuraa 
Viestejä21228
Liittynyt16.3.2005

Pitäisi oppia pois koko sekventiaalisesta ajattelutavasta ohjelmia suunniteltaessa. Luontaisestihan moni ongelma on rinnakkainen, ja ihminenkin ehkä ajattelee niin ennenkuin opiskelee ohjelmointia. Valitettavasti ohjelmoinnin alkeisopetuksessa runnnotaan tulevien koodarien päähän sekventiaalisuuden paradigma, ja algoritmien laadinnassakin pakotetaan aluksi sekventialisoimaan luontaisesti rinnakkaisetkin ongelmat. Vasta hyvin edistyneille ohjelmoijille aletaan taas sallia rinnakkaista ajattelutapaa, tosin sittenkin ensin sekvensialisoidun ratkaisun pilkkomisessa - kun luonnollinen rinnakkaisuus on ensin kadotettu - ja vain riittävän isoissa ja kömpelöissä paloissa. Vahinko on jo joka tapauksessa tässä vaiheessa peruuttamattomasti tapahtunut. Kirjoitettaessa ongelma sekventiaalisella kielellä sekventiaaliseksi koodiksi, hävitetään paljon ongelman rinnakkaisuutta palauttamattomalla tavalla. Tavalla, jota ei enää voida takaisinpäin laskea missään kääntämisen yms. käsittelyn vaiheissa.

Kyllähän muutokseen toki apuja tarvitaan kääntäjiltä, käyttöjärjestelmiltä, väliohjelmistoilta yms. infraltakin. Ja kirjastoja, sekä ehkä uusia kieliäkin tarvitaan.

Se oli kivaa niin kauan kuin sitä kesti.

Seppo_Pietikainen
Seuraa 
Viestejä7615
Liittynyt18.10.2007
odyseus
Kysymys (C ja ASM) ohjelmoijille.

Nyt kun julkisuudessakin on "isojen tekijöiden toimesta" annettu ohjelmoijille varoituksia, että "varautukaa tuhansiin ytimiin", eli että ohjelmoijien olisi jo nyt alettava varautumaan siihen, että tietokoneissa on jo lähitulevaisuudessa useampia kuin 32 ydintä, ja että nykyiset ohjelmointikäytänöt ovat tällaiselle arkkitehtuurille sopimattomia.

Kysynkin nyt mielipidettä, että miten tähän pitaisi varautua?

Normaalin PHP, ASP, Viaual Basic, Java jne. -ohjelmoijan ei taatusti tarvitse tietää asiasta höykäsen pölähtävää, mutta entä C/C++ koodarit, varsinkin me/te, jotka toteuttavat laitteistotason koodia, sulautettuja järjestelmiä, aikakriittisiä ratkaisuja, monen käyttäjän transaktiojärjestelmiä jne..




Väärin. Jos aikoo käyttää säikeitä on pakko paneutua säikeisiin liittyvään problematiikkaan, oli käytetty ohjelmointikieli mikä hyvänsä.
Kaikilla ohjelmointikielillä on oma säikeisiin liittyvä yhteisten resurssien hallinnointiin tarkoitettu semantiikkansa, ja väärinkäytettynä (tai väärinymmärrettynä) lopputulos on helposti katastrofi...

Java "synchronized" on väärinkäytettynä ja väärin ymmärrettynä todella vaarallinen, erityisesti aidoissa SMP-järjestelmissä.

C/C++ koodinvääntäjien kannattaa paneutua standardeihin, erityisesti POSIX -threadeihin (erityisesti, kun POSIX-säikeet ovat toistaiseksi ainoa standardoitu säijemalli ).


Miten esimerkiksi normaalissa C:llä toteutetussa ohjelmistossa olisi otettava huomioon threadit ja prosessit? Perinteisestihän on "thredattu" jos jokin toiminto vie oletettavasti sen verran aikaa, että käyttäjä huomaa toiminnossa viivettä. Tällöin jaetaan prosessi kahteen tai threadataan... Mutta miten on esimerkiksi 1000 ytimen kanssa? Onko koodaajan threadattava jo hyvin pieniä pätkiä koodia, periaatteessa siis jokainen funktio?



Kannattaa miettiä mitä voi ja kannattaa rinnallistaa. Säikeistäminen ei ole ilmaista. Käyttöjärjestelmä joutuu joka tapauksessa suorittamaan skedulointia eri säikeiden välillä, ja säikeistäminen edellyttää aina säikeiden välistä koordinointia.

Koordinoinnin implementoiminen mutexien ja ehtomuuttujien avulla ei välttämättä ole helppoa, sen sijaan on tavattoman helppoa sarjallistaa kaikki säikeet yhden mutexin tai ehtomuuttujan perään, ja sitten ihmetellään silmät soikeina miksi 1000 cpun järjestelmä toimii hitaammin kuin yhden cpun järjestelmä... (sattuu olemaan omakohtaista kokemusta 64-cpun järjestelmän hyytymisestä väärin suunnitellun ja implementoidun säikeistetyn sovelluksen kanssa pähkäilystä - sadat säikeet kilpailivat samasta mutexista sangen kiivaalla tahdilla...)


Vai onko homma yksinkertaisesi niin, että "varoitukset" jylisevät vain kääntäjiä kehittäville tahoille ja "ceetä" kirjoitetaan samaan tapaan kuin ennenkin?



C/C++ kääntäjät eivät yleensä tiedä säikeistä yhtään mitään, eivätkä siis varoittelekaan.


Threadien tekeminenhän vie kuitnkin aikaa ja varsinkin eri threadien ja prosessien hallinta altistaa virheille ja muistivuodoille esimerkiksi sen vuoksi, että jotain "semaphorea" ei ole luotu, jotain kriittistä objektia ei ole lukittu, yritetään lukea jotain mitä toinen threadi ei ole vielä tehnyt, muistissa ei ole tilaa jne...



Jeps... Säikeiden välinen koordinointi on haasteellista. Säikeille yhteisten resurssien hallinnointi kannattaa suunnitella erittäin tarkasti.


Nimim. Threadasinko turhaan?



Ei välttämättä, mutta paneudu ja tutustu asiaan kunnolla....
Eritisesti kannattaa paneutua koordinointimekanismeihin (mutexit, ehtomuuttujat, ja vähemmän tunnetut Read/Write -lukot (osa UNIX-98:aa)).

--
Seppo P.
Kreationismi perustuu tietämättömyyteen, se sikiää tietämättömyydestä ja siitä sikiää tietämättömyyttä. Tietämättömyyden levittäminen on kreationismin elinehto ja tietämättömyydessä rypeminen on kreationistin luonnollinen elämisenmuoto

Vierailija
Seppo_Pietikainen
odyseus
Kysymys (C ja ASM) ohjelmoijille.

Nyt kun julkisuudessakin on "isojen tekijöiden toimesta" annettu ohjelmoijille varoituksia, että "varautukaa tuhansiin ytimiin", eli että ohjelmoijien olisi jo nyt alettava varautumaan siihen, että tietokoneissa on jo lähitulevaisuudessa useampia kuin 32 ydintä, ja että nykyiset ohjelmointikäytänöt ovat tällaiselle arkkitehtuurille sopimattomia.

Kysynkin nyt mielipidettä, että miten tähän pitaisi varautua?

Normaalin PHP, ASP, Viaual Basic, Java jne. -ohjelmoijan ei taatusti tarvitse tietää asiasta höykäsen pölähtävää, mutta entä C/C++ koodarit, varsinkin me/te, jotka toteuttavat laitteistotason koodia, sulautettuja järjestelmiä, aikakriittisiä ratkaisuja, monen käyttäjän transaktiojärjestelmiä jne..




Väärin. Jos aikoo käyttää säikeitä on pakko paneutua säikeisiin liittyvään problematiikkaan, oli käytetty ohjelmointikieli mikä hyvänsä.
Kaikilla ohjelmointikielillä on oma säikeisiin liittyvä yhteisten resurssien hallinnointiin tarkoitettu semantiikkansa, ja väärinkäytettynä (tai väärinymmärrettynä) lopputulos on helposti katastrofi...

Java "synchronized" on väärinkäytettynä ja väärin ymmärrettynä todella vaarallinen, erityisesti aidoissa SMP-järjestelmissä.

C/C++ koodinvääntäjien kannattaa paneutua standardeihin, erityisesti POSIX -threadeihin (erityisesti, kun POSIX-säikeet ovat toistaiseksi ainoa standardoitu säijemalli ).


Miten esimerkiksi normaalissa C:llä toteutetussa ohjelmistossa olisi otettava huomioon threadit ja prosessit? Perinteisestihän on "thredattu" jos jokin toiminto vie oletettavasti sen verran aikaa, että käyttäjä huomaa toiminnossa viivettä. Tällöin jaetaan prosessi kahteen tai threadataan... Mutta miten on esimerkiksi 1000 ytimen kanssa? Onko koodaajan threadattava jo hyvin pieniä pätkiä koodia, periaatteessa siis jokainen funktio?



Kannattaa miettiä mitä voi ja kannattaa rinnallistaa. Säikeistäminen ei ole ilmaista. Käyttöjärjestelmä joutuu joka tapauksessa suorittamaan skedulointia eri säikeiden välillä, ja säikeistäminen edellyttää aina säikeiden välistä koordinointia.

Koordinoinnin implementoiminen mutexien ja ehtomuuttujien avulla ei välttämättä ole helppoa, sen sijaan on tavattoman helppoa sarjallistaa kaikki säikeet yhden mutexin tai ehtomuuttujan perään, ja sitten ihmetellään silmät soikeina miksi 1000 cpun järjestelmä toimii hitaammin kuin yhden cpun järjestelmä... (sattuu olemaan omakohtaista kokemusta 64-cpun järjestelmän hyytymisestä väärin suunnitellun ja implementoidun säikeistetyn sovelluksen kanssa pähkäilystä - sadat säikeet kilpailivat samasta mutexista sangen kiivaalla tahdilla...)


Vai onko homma yksinkertaisesi niin, että "varoitukset" jylisevät vain kääntäjiä kehittäville tahoille ja "ceetä" kirjoitetaan samaan tapaan kuin ennenkin?



C/C++ kääntäjät eivät yleensä tiedä säikeistä yhtään mitään, eivätkä siis varoittelekaan.


Threadien tekeminenhän vie kuitnkin aikaa ja varsinkin eri threadien ja prosessien hallinta altistaa virheille ja muistivuodoille esimerkiksi sen vuoksi, että jotain "semaphorea" ei ole luotu, jotain kriittistä objektia ei ole lukittu, yritetään lukea jotain mitä toinen threadi ei ole vielä tehnyt, muistissa ei ole tilaa jne...



Jeps... Säikeiden välinen koordinointi on haasteellista. Säikeille yhteisten resurssien hallinnointi kannattaa suunnitella erittäin tarkasti.


Nimim. Threadasinko turhaan?



Ei välttämättä, mutta paneudu ja tutustu asiaan kunnolla....
Eritisesti kannattaa paneutua koordinointimekanismeihin (mutexit, ehtomuuttujat, ja vähemmän tunnetut Read/Write -lukot (osa UNIX-98:aa)).



Olen eri mieltä kanssasi noiden Java, .NET ja muiden hörhötysten kanssa, sillä niissä nuo "matalamman tason" säikeet pitäisi mielestäni toteuttaa virtuaalikoneen tasolla eikä ohjelmoijan tekeminä. Eli muulloin kuin perinteisesti: = juuri silloin kun käyttäjältä odotetaan palautetta tai joku ohjelman osa vie prosessiaikaa ja käyttäjä joutuu siten odottelemaan.

On toki HYVÄ jos näillä kielillä tekijä ymmärtää säikeet myös todenteolla, mutta silti uskon, että "syvemmälle menevä" säikeytys on tapahduttava virtuaalikoneessa (java, asp, .NET, PHP......).

Alkuperäinen kysymykseni kuuluikin lähinnä sille tasolle koodia, jossa tehdään esimerkiksi laiteajureita jne. kilkkeitä, joissa ollaan vähintään käyttöjärjestelmätasossa tai sitten jopa prossun alemmalla renkaalla.. Tai sitten sillä ylemmällä tasolla, missä pitää antaa threadeille itse prioriteetteja, jotta joku homma hoituu nopeammin...

Mainitsit, että "C/C++ kääntäjät eivät yleensä tiedä säikeistä yhtään mitään, eivätkä siis varoittelekaan.", mutta tätä asiaa tämä kysymys oikeastaan koskeekin. Pitääkö uusien kääntäjien alkaa välittämään tästä vai koodaajan? Onko vastuu siis kääntäjiä ja virtuallikoneita tekevillä tahoilla vai loppukäyttäjän sovellusohjelman tekijällä?

Itse olen koodannut C:tä noin 20 vuotta ja tehnyt koodia myös Win32API:lle, mutta en koskaan esimerkiksi noille MFC jne. luokkakirjastohörhöille... No jaa, Borlandin C++ Builderia on tullut käytettyä... Pääsääntöisesti väännämme koodia Linukoille ja koodina Ansi C (Posix) eikä edes C++. Mutexit ja niihin liittyvät lukitukset jne ovat kyllä tuttuja.

MaKo71
Seuraa 
Viestejä1467
Liittynyt15.11.2006
odyseus

Mainitsit, että "C/C++ kääntäjät eivät yleensä tiedä säikeistä yhtään mitään, eivätkä siis varoittelekaan.", mutta tätä asiaa tämä kysymys oikeastaan koskeekin. Pitääkö uusien kääntäjien alkaa välittämään tästä vai koodaajan?



Todennäköisesti kääntäjät oppivat kyllä asiaa ymmärtämään. C-kieltä on käytetty mm. rautasuunnittelussa ja rautahan on perinteisesti hyvinkin rinnakkaista (ja vaikeasti debugattavaa). Esimerkiksi PACT:n XPP:tä ohjelmoidaan C:llä:

http://www.pactxpp.com/main/index.php

odyseus

Onko vastuu siis kääntäjiä ja virtuallikoneita tekevillä tahoilla vai loppukäyttäjän sovellusohjelman tekijällä?



Pitkän päälle varmaan sekä että. Jos multa kysyttäisiin, että miten tulevaisuuden prosessoreja ohjelmoidaan, niin sanoisin, että kääntäjät hoitavat alemman tason rinnakkaistamisen, ja ihmiset rinnakkaistavat MP (Message Passing) -paradigmalla. Eriäviä mielipiteitä on varmasti, esim. jotkut vannovat DF-kielten nousuun rinnakkaisuuden kasvaessa.

Vierailija

Jos algoritmi ei tue rinnakkaistusta, niin ei sitä mikään kääntäjä rinnakkaista.

Esim eniten tehoa vaativat hommat, videon pakkaus ja purkaminen, ei rinnakkaistu. Irvokasta.

Okei, 5 vaihetta rinnakkaistuu, mutta yksi ei. Se tulisi olemaan pullonkaula, joten on ihan turha rinnakkaistaa mitään. Hitain lenkki määrää kokonaisläpimenon.

Videon voi rinnakkaistaa, jos tehdään tehoa syöviä kompromisseja tai lisätään latenssia.

Tulevaisuus on muuten asynkronisten prosessorien, koska ne säästää akkua ja ovat helppoja ohjelmoida. Ks. esim

http://www.prosessori.fi/uutiset/uutinen2.asp?id=46243

Seppo_Pietikainen
Seuraa 
Viestejä7615
Liittynyt18.10.2007

Pistetty ilman kohdistusta mihinkään tiettyyn vastaukseen...

Jotkut C/C++ kääntäjät osaavat generoida "rinnakkaista" koodia pragmojen avulla (Intel/x86_64/IA64, HP-UX/IA64). Itselläni ei ole kokemusta moisten käytöstä, ja hieman epäilen toimivuutta...

--
Seppo P.
Kreationismi perustuu tietämättömyyteen, se sikiää tietämättömyydestä ja siitä sikiää tietämättömyyttä. Tietämättömyyden levittäminen on kreationismin elinehto ja tietämättömyydessä rypeminen on kreationistin luonnollinen elämisenmuoto

MaKo71
Seuraa 
Viestejä1467
Liittynyt15.11.2006
Lektu-Elli
Jos algoritmi ei tue rinnakkaistusta, niin ei sitä mikään kääntäjä rinnakkaista.



Tottakai!

Lektu-Elli

Tulevaisuus on muuten asynkronisten prosessorien, koska ne säästää akkua ja ovat helppoja ohjelmoida. Ks. esim

http://www.prosessori.fi/uutiset/uutinen2.asp?id=46243




Jeps. Asynkronisuus ei toki tee itse prosessorin ohjelmoimisesta (s.o. ohjelmakoodin vääntämisestä) helpompaa, mutta sen toteuttamisesta kylläkin; tai sekin riippuu paljolti toteutettavan piirin monimutkaisuudesta. Mitä mutkikkaampia piirejä suunnitellaan, sen helpommin se on tehtävissä asynkronisilla tekniikoilla.

ilmaisin
Seuraa 
Viestejä1285
Liittynyt2.7.2005

Onko tässä prosessoriydinten lukumääräkilpailussa nyt jotain samaa kuin siinä takavuosien idioottimaisessa kellotaajuuskilpailussa? Ainakin näin maallikkona on kohtuullisen hankala tajuta, mitä hyötyä tuosta ydinten lukumäärän kiihkonomaisesta kasvattamisesta on.

Vierailija
ilaiho
Onko tässä prosessoriydinten lukumääräkilpailussa nyt jotain samaa kuin siinä takavuosien idioottimaisessa kellotaajuuskilpailussa? Ainakin näin maallikkona on kohtuullisen hankala tajuta, mitä hyötyä tuosta ydinten lukumäärän kiihkonomaisesta kasvattamisesta on.



Prosessori valmistajat ovat juuttuneet paikalleen. Samalla ku GPU saa lisää tehoa laskea vaikkapa ankanpoikasia, sukkaa CPU pahasti. Yrittävät paikata ongelmiaan lisäämällä enemmän prosessoreita.

Vierailija

Näin mutu-pohjalta väittäisin, että nuo uudet tuhannet ytimet "yhdessä chipissä" ovat sellaisia, joilla on omaa sisäistä rammia "riittävästi" suorittimaan toimintaansa, eivätkä näin ole riippuvia keskusmuistista tehdessään toimintoja kuten nykyisin on monicpu-ympäristöissä? Eikös sääntönä ole nykyisin, että säikeiden määrää yksiprosessorisessa ympäristössä rajoittaa rammin määrä.

Että tuskin nuo tuhannet ytimet ajavat koodia ainoastaan cpu:n ulkoisessa rammissa. Kaikille ytimille yhteisen ulkoinen rammin käyttö 1000-ytimisessä ympäristössä olisikin sitten se mass-strorage (nykyinen ram-malli), jota kenties käyttäisi yksiytimiseen verrattavissa oleva main-cpu.

Sivut

Uusimmat

Suosituimmat