Permalänk
Entusiast

Hitta flaskhals i Matlab?

Jag sitter och skriver på ett exjobb som går ut på att lösa lite differentialekvationer numeriskt i Matlab. I korthet löser jag ett linjärt ekvationssystem i ett antal celler som jag itererar över. Koden är inte optimerad på prestanda än så länge och kommer eventuellt inte bli på grund av tidsbrist men när jag satt och tittade lite på vad som händer när den räknar så blev jag förvånad. 100 celler går på under en sekund. 1000 celler tar ca 30 sekunder och 10000 celler orkade jag inte vänta på så gav upp efter tio minuter. När jag kollar på processorbelastningen så tar Matlab ca 20 %. Koden är enkeltrådad och jag kan rätt tydligt se vilken kärna det är som får jobba med den. RAM är inte heller något problem för det går bara åt en ca 700 MB för tillfället. Det kan bli ett problem senare men nu verkar Matlab kunna hålla alla variabler i RAM.

Så vad är det som tar så extremt lång tid? Vad väntar datorn på? Är det att läsa data från RAM till cache som tar lång tid eftersom själva beräkningen inte är tung? För det verkar ju inte som om det är RAM som krånglar då jag har 16 GB tillgängligt och Matlab borde använda allt den behöver.

Vore även trevligt om det fanns ett generellt verktyg för har en liknande fundering kring ett spel där spelet säger att prestandan begränsas av min processor men enhetshanterar säger att jag peakar på 80 % och oftast ligger jag runt 50 % så bevisligen finns det massa prestanda kvar att hämta.

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24

Permalänk
Medlem

Vilken algoritm kör du? Kan mycket väl vara så att du maxar en kärna och iom seriell algoritm blir en kärna maxad och de andra oelastade.

Visa signatur

Citera om du vill ha svar.

Permalänk

Nu har jag aldrig sysslat med matlab och är inte heller en stjärna på matematik. Men hade jag själv fått samma fenomen som du anger när jag själv kodar något så känns det inte som att det är hårdvaran utan själva algoritmen som bromsar ( Återigen så vet jag inte hur matlab fungerar). Det låter alltså som att körtiden skenar iväg med storleken på input istället för att vara linjär eller liknande tidskomplexitet. Kan det kanske vara något sådant och inte hårdvaran?

Visa signatur

Intel 4670K| 16GB | Galax 1080 | Corsair AX 750

Permalänk
Medlem

Skulle gissa på RAM-latensen.

Permalänk
Medlem

Bara för att det är ett linjärt ekvationssystem betyder det inte att din lösning är linjär till antalet celler. http://en.wikipedia.org/wiki/Time_complexity

Permalänk
Medlem

Att profilera koden (profile on;kod;profile viewer; ) kan kanske vara ett sätt att se vad som tar mer tid.

Permalänk
Entusiast
Skrivet av muppens:

Vilken algoritm kör du? Kan mycket väl vara så att du maxar en kärna och iom seriell algoritm blir en kärna maxad och de andra oelastade.

Det som tar mycket tid verkar vara lösningen av det linjära ekvationssystemet som för tillfället bara har tre variabler och det kommer inte bli så mycket större. Sen är det Gauss-Seidel som görs över alla cellerna.
Jag vet redan att den bara använder en kärna för algoritmen går inte att köra seriellt på ett smidigt sätt. Varje iteration beror på lösningen av föregående cell och så vidare. Som sagt så kan jag se vilken kärna som används men den går inte över 20 %.

Skrivet av Belgaar:

Troligen så kör du en algoritm som ökar kvadratiskt. Vilket vid stora tal tar väldigt lång tid. Kan inte säga vilken du ska byta till men det är där problemet ligger.

Som sagt Gauss-Seidel och tror inte jag kan byta hur som helst för det är ett CFD-problem som kräver en iterativ lösning. Eller tekniskt sett hade det gått att lösa som ett linjärt ekvationssystem men det skulle haverera för stora matriser senare.

Skrivet av Tullmeister:

Nu har jag aldrig sysslat med matlab och är inte heller en stjärna på matematik. Men hade jag själv fått samma fenomen som du anger när jag själv kodar något så känns det inte som att det är hårdvaran utan själva algoritmen som bromsar ( Återigen så vet jag inte hur matlab fungerar). Det låter alltså som att körtiden skenar iväg med storleken på input istället för att vara linjär eller liknande tidskomplexitet. Kan det kanske vara något sådant och inte hårdvaran?

Kommersiell CFD-mjukvara kör samma algoritm och klarar av att belasta processorn väldigt mycket mer. Men de kanske kör lite annan voodoo för att göra det mer effektivt.

Att den inte löste det för extremt många celler kan bero på numeriska problem som ställer till det. Jag analyserade inte lösningen ordentligt men det är möjligt att det krånglar med toleranser för konvergens i något steg. Eller att matlab bråkar i vanlig ordning. Men ja tiden ökar rätt mycket vid större körningar.

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24

Permalänk
Medlem
Skrivet av Zotamedu:

Det som tar mycket tid verkar vara lösningen av det linjära ekvationssystemet som för tillfället bara har tre variabler och det kommer inte bli så mycket större. Sen är det Gauss-Seidel som görs över alla cellerna.
Jag vet redan att den bara använder en kärna för algoritmen går inte att köra seriellt på ett smidigt sätt. Varje iteration beror på lösningen av föregående cell och så vidare. Som sagt så kan jag se vilken kärna som används men den går inte över 20 %.

Som sagt Gauss-Seidel och tror inte jag kan byta hur som helst för det är ett CFD-problem som kräver en iterativ lösning. Eller tekniskt sett hade det gått att lösa som ett linjärt ekvationssystem men det skulle haverera för stora matriser senare.

Kommersiell CFD-mjukvara kör samma algoritm och klarar av att belasta processorn väldigt mycket mer. Men de kanske kör lite annan voodoo för att göra det mer effektivt.

Att den inte löste det för extremt många celler kan bero på numeriska problem som ställer till det. Jag analyserade inte lösningen ordentligt men det är möjligt att det krånglar med toleranser för konvergens i något steg. Eller att matlab bråkar i vanlig ordning. Men ja tiden ökar rätt mycket vid större körningar.

Har du fått svar på dina frågor nu? Koden är enkeltrådad, hur skulle du kunna få ut mer prestanda?

För att belasta processorn mer måste du göra koden flertrådad.

Permalänk
Entusiast
Skrivet av kobb3:

Har du fått svar på dina frågor nu? Koden är enkeltrådad, hur skulle du kunna få ut mer prestanda?

För att belasta processorn mer måste du göra koden flertrådad.

Nej inte riktigt för att den ensamma tråden bara belastar en kärna 20 %. Då är det ju inte uppenbart att fler trådar löser det.

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24

Permalänk
Medlem

Kan du formulera om problemet?
Lösa det genom att först göra en vettig faktorisering, householder-transform eller liknande för att sedan få ett enklare system som kanske är mer stabilt för G-S iterationerna alternativt som på ett mer direkt sätt kan lösas genom återsubstitution...

Jag vet inte riktigt, det är svårt att ge konkreta förslag utan en mer formell problembeskrivning samt beskrivning hur din algoritm ser ut.

Visa signatur

weeeee

Permalänk
Medlem

Har du gjort Gauss-Seidelalgoritmen själv, eller är den inbyggd i Matlab? Jag tror att det finns andra iterativa algoritmer inbyggda (gmres?, bicstab?) du kan prova i så fall.
MVH
squse

La till iterativa
Permalänk
Medlem
Skrivet av Zotamedu:

Jag sitter och skriver på ett exjobb som går ut på att lösa lite differentialekvationer numeriskt i Matlab. I korthet löser jag ett linjärt ekvationssystem i ett antal celler som jag itererar över. Koden är inte optimerad på prestanda än så länge och kommer eventuellt inte bli på grund av tidsbrist men när jag satt och tittade lite på vad som händer när den räknar så blev jag förvånad. 100 celler går på under en sekund. 1000 celler tar ca 30 sekunder och 10000 celler orkade jag inte vänta på så gav upp efter tio minuter. När jag kollar på processorbelastningen så tar Matlab ca 20 %. Koden är enkeltrådad och jag kan rätt tydligt se vilken kärna det är som får jobba med den. RAM är inte heller något problem för det går bara åt en ca 700 MB för tillfället. Det kan bli ett problem senare men nu verkar Matlab kunna hålla alla variabler i RAM.

Så vad är det som tar så extremt lång tid? Vad väntar datorn på? Är det att läsa data från RAM till cache som tar lång tid eftersom själva beräkningen inte är tung? För det verkar ju inte som om det är RAM som krånglar då jag har 16 GB tillgängligt och Matlab borde använda allt den behöver.

Vore även trevligt om det fanns ett generellt verktyg för har en liknande fundering kring ett spel där spelet säger att prestandan begränsas av min processor men enhetshanterar säger att jag peakar på 80 % och oftast ligger jag runt 50 % så bevisligen finns det massa prestanda kvar att hämta.

Det låter som om du räknar om tidigare slutförda uträkningar. För att räkna ut det 101:a talet behöver du räkna ut de 100 innan osv, vilket skulle leda till den dramatiska tidskomplexitet du beskriver. Istället för att räkna om alla tidigare värden för varje iteration bör du låta progammet memorera dem i en vektor eller liknande datastruktur.

Visa signatur

Kom-pa-TI-bilitet

Permalänk

Gör som det är sagt tidigare i tråden, profilera. Det inbyggda verktyget i Matlab är väldigt smidigt och du bör snabbt kunna konstatera vilken rad som är långsammast. Använder du matlabs funktioner på felaktigt sätt så förlorar du snabbt all prestanda.

Permalänk
Medlem
Skrivet av Zotamedu:

Nej inte riktigt för att den ensamma tråden bara belastar en kärna 20 %. Då är det ju inte uppenbart att fler trådar löser det.

20% av en kärna?!? Det låter ju grymt lite. Så du menar att processorn jobbar ca 5% av sin fulla kapacitet? Eftersom du har 4 kärnor.

Om så är fallet låter det underligt.

Permalänk

Kan också vara så att din processor har för lite cache-minne och då kommer att måsta söka högre upp i minnet rätt ofta. Sådant slöar rätt ofta ner processer också.

Vilken Gauss-Seidel-mjukvara använder du? Mathworks är ju ena djeflar på att skriva fortran-matlab så deras egna saker brukar vara grymt optimerade, men "sånt man hittar på nätet" kan ju vara av varierande kvalla. Iofs brukar mathworks forum innehålla en hel del matnyttigt.

Lek lite med MatLabs profiler, den är fin.

Permalänk
Entusiast
Skrivet av mounte:

Kan du formulera om problemet?
Lösa det genom att först göra en vettig faktorisering, householder-transform eller liknande för att sedan få ett enklare system som kanske är mer stabilt för G-S iterationerna alternativt som på ett mer direkt sätt kan lösas genom återsubstitution...

Jag vet inte riktigt, det är svårt att ge konkreta förslag utan en mer formell problembeskrivning samt beskrivning hur din algoritm ser ut.

Egentligen är det inte tidsåtgången som oroar mig utan det faktum att den inte belastar processorn alls.

Problemet är en massbalans i en dimension med konvektion, dispersion, reaktion och än så länge enkla källtermer. Programmet är helt egenskrivet och räknar fram en koncentrationsprofil baserat på massbalansen. I varje cell har jag olika storlekar på de partiklar som reagerar så i varje cell ska det inte bara lösas en massbalans med transport in och ut ur cellen för varje partikel storlek utan jag ska även lösa en balans för hur storleken förändras. Just förändringen av storlek löses med ett linjärt ekvationssystem som just nu har tre obekanta och kommer aldrig ha fler än 15. Den biten går fort. Det som tar tid är att lösa massbalansen för alla celler.

Metoden går ju ut på att jag gissar en koncentration för alla celler och sedan använder jag den gissningen och min massbalans för att räkna fram en bättre koncentration och sedan littererar man som en galning tills man får en lösning.

Skrivet av squse:

Har du gjort Gauss-Seidelalgoritmen själv, eller är den inbyggd i Matlab? Jag tror att det finns andra iterativa algoritmer inbyggda (gmres?, bicstab?) du kan prova i så fall.
MVH
squse

Den är helt egenbyggd eftersom det är det exjobbet går ut på.

Skrivet av Teknocide:

Det låter som om du räknar om tidigare slutförda uträkningar. För att räkna ut det 101:a talet behöver du räkna ut de 100 innan osv, vilket skulle leda till den dramatiska tidskomplexitet du beskriver. Istället för att räkna om alla tidigare värden för varje iteration bör du låta progammet memorera dem i en vektor eller liknande datastruktur.

Ja det är så jag måste göra för att lösa problemet. Det är ju en iterativ metod så lösningen av det 101a talet beror av värdet på det 100e. Tidigare uträknade tal sparas redan i en vektor eftersom algoritmen går igenom alla tal från början till slut och räknar fram ett nytt tal baserat på talen bredvid. Så ett nytt värde för talet i fås av i-1 och i+1. Så löser man från i upp till antalet celler och sedan börjar man om från ett och gör ett svep till fram tills dess man har hittat en konvergerande lösning. Så jag sparar de senaste lösningarna i en vektor och inget annat.

Skrivet av Korkskruv:

Gör som det är sagt tidigare i tråden, profilera. Det inbyggda verktyget i Matlab är väldigt smidigt och du bör snabbt kunna konstatera vilken rad som är långsammast. Använder du matlabs funktioner på felaktigt sätt så förlorar du snabbt all prestanda.

Jag använder rätt få av Matlabs funktioner för tillfället. Har kört profileraren för att få fram tiderna men den gav inte så mycket information. Ska ta och köra en omgång till i morgon och se om jag kan lura ut lite mer från den.

Skrivet av kobb3:

20% av en kärna?!? Det låter ju grymt lite. Så du menar att processorn jobbar ca 5% av sin fulla kapacitet? Eftersom du har 4 kärnor.

Om så är fallet låter det underligt.

Ja det är ju det som gör mig så fundersam. Det är inte datorn i signaturen som används utan det är en fyrkärnig i7 med HT så har 8 trådar att leka med. Har för mig att det är en Nahelem men kommer inte ihåg exakt modell. Enligt enhetshanteraren så tar Matlab ca 20 % CPU och tittar jag på varje enskild logisk kärna så ser jag tydligt vilken det är som faktiskt arbetar och den ligger väldigt lågt. Så något annat sätter stopp.

Skrivet av boomhowler:

Kan också vara så att din processor har för lite cache-minne och då kommer att måsta söka högre upp i minnet rätt ofta. Sådant slöar rätt ofta ner processer också.

Vilken Gauss-Seidel-mjukvara använder du? Mathworks är ju ena djeflar på att skriva fortran-matlab så deras egna saker brukar vara grymt optimerade, men "sånt man hittar på nätet" kan ju vara av varierande kvalla. Iofs brukar mathworks forum innehålla en hel del matnyttigt.

Lek lite med MatLabs profiler, den är fin.

Det var cacheminnet som var min hypotes. Frågan är om det finns ett sätt att kolla om så är fallet för då är det nog inte mycket jag kan göra åt det.

Jag använder egenskrivna saker för att det är en del av exjobbet. Ingen utmaning att bara använda färdiga saker utan tanken är att jag ska lära mig lite på vägen också.

Egentligen är det inte viktigt att optimera för det har jag inte tid med i exjobbet. Det är en hård tidsplan som det är om jag ska göra allt som min examinator vill ha gjort. Hårdare optimering får han göra själv sen om jag lyckas få till arbetet tillräckligt bra för att det faktiskt ska användas senare. Tar körningen för lång tid får jag helt enkelt använda en grövre mesh. Hade varit grymt kul att pilla med optimering också för det har jag aldrig gjort innan men tyvärr har jag inte riktigt möjligheten för tillfället.

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24

Permalänk

En riktig dödare i matlab är att inte fördefinera storleken på matriser och sen utöka dom.
Använd zeros för att fördefiniera storleken.
Men det är så jävla basic att jag inte tror du missat det.

Mitt sista tips är C-kod.

Visa signatur

Nja.

Permalänk
Entusiast
Skrivet av Kaptenstjärt:

En riktig dödare i matlab är att inte fördefinera storleken på matriser och sen utöka dom.
Använd zeros för att fördefiniera storleken.
Men det är så jävla basic att jag inte tror du missat det.

Mitt sista tips är C-kod.

Nej inga matriser som ökar storlek. Allt är fördefinierat innan jag börjar räkna med det.

Tyvärr hinner jag inte lära mig C eller för den delen FORTRAN innan arbetet ska vara klart. Dessutom är det en modul som ska in i en större matlabmodel i slutändan så tror inte det är så populärt att porta den till ett annat språk.

Edit: Enligt profiler så tar raden:

global const mesh

hela 20 % av den totala körtiden. const och mesh är båda structures med konstanter respektive detaljer om min mesh som båda behövs för att köra funktionsfilen. Det är alltså en underfunktion som tar större delen av tiden. Jag gjorde en provkörning med 1000 celler och funktionen anropas då 230 000 gånger. Jag trodde inte att det skulle ta så lång tid att sätta upp globala variabler. Tyvärr känns det inte som om jag har något val då det är för mycket data för att det ska vara rimligt att skicka det som indata till funktionen. Vidare tar en rad som säger:

C(:,i) = balance_m(C,i)

Väldigt lång tid med en bra bit över hälften av körtiden. Matrisen C är redan ansatt till rätt storlek innan loopen körs så den ändrar inte storlek. Det är bara värdena inne i den som ändras. Det är för övrigt den funktionen som körs så många gånger och där global-kommandot tar så mycket tid.

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24

Permalänk
Skrivet av Zotamedu:

Nej inga matriser som ökar storlek. Allt är fördefinierat innan jag börjar räkna med det.

Tyvärr hinner jag inte lära mig C eller för den delen FORTRAN innan arbetet ska vara klart. Dessutom är det en modul som ska in i en större matlabmodel i slutändan så tror inte det är så populärt att porta den till ett annat språk.

Edit: Enligt profiler så tar raden:

global const mesh

hela 20 % av den totala körtiden. const och mesh är båda structures med konstanter respektive detaljer om min mesh som båda behövs för att köra funktionsfilen. Det är alltså en underfunktion som tar större delen av tiden. Jag gjorde en provkörning med 1000 celler och funktionen anropas då 230 000 gånger. Jag trodde inte att det skulle ta så lång tid att sätta upp globala variabler. Tyvärr känns det inte som om jag har något val då det är för mycket data för att det ska vara rimligt att skicka det som indata till funktionen. Vidare tar en rad som säger:

C(:,i) = balance_m(C,i)

Väldigt lång tid med en bra bit över hälften av körtiden. Matrisen C är redan ansatt till rätt storlek innan loopen körs så den ändrar inte storlek. Det är bara värdena inne i den som ändras. Det är för övrigt den funktionen som körs så många gånger och där global-kommandot tar så mycket tid.

Deklarerar du de globala variablerna i funktionen och sen anropas funktionen 230000 ggr?

Man kan göra vissa enskilda delar i C, man behöver inte porta allt.

Skickades från m.sweclockers.com

Visa signatur

Nja.

Permalänk
Entusiast
Skrivet av Kaptenstjärt:

Deklarerar du de globala variablerna i funktionen och sen anropas funktionen 230000 ggr?

Man kan göra vissa enskilda delar i C, man behöver inte porta allt.

Skickades från m.sweclockers.com

Nej de deklareras i två andra funktioner. En som heter load_mesh och en som heter load_constants. Där ansätts massa varieabler i de två strukturerna const och mesh. Dessa variabler behövs som indata för att räkna funktionen och för att slippa att ha tre rader långt anrop på funktionen så är de satta som globala. I början av funktionen balance_m som körs 230000 gånger så måste jag ju säga att mesh och const är globala.

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24

Permalänk
Hedersmedlem
Skrivet av Zotamedu:

Dessa variabler behövs som indata för att räkna funktionen och för att slippa att ha tre rader långt anrop på funktionen så är de satta som globala.

Blir det bättre med ett långt anrop? Global verkar vara långsamt men också eventuellt förhindra annan optimering: http://stackoverflow.com/questions/7888899/global-could-be-ve...

Permalänk
Entusiast
Skrivet av Elgot:

Blir det bättre med ett långt anrop? Global verkar vara långsamt men också eventuellt förhindra annan optimering: http://stackoverflow.com/questions/7888899/global-could-be-ve...

Har inte testat det faktiskt. Det var intressant läsning det där. Ska se om jag kan lägga lite tid på att göra om mina globala variabler till MATLAB handle object som det stod något om i en av länkarna. Får se hur mycket jobb det är bara för fördelen med global är att den är väldigt smidig att använda i kombination med strukturer. Jag har ju rätt olika typer av data och alla delar behöver inte ha tillgång till allt.

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24

Permalänk
Medlem

En typisk matlab fråga: du kör inte en massa for-loops? Dessa är ju Matlab känd för att vara riktigt långsam på.
Det låter som om du skulle kunna ha en hel massa for-loopar som är nästlade i varandra.
Vectorisera! Kom ihåg att Matlab står för 'MATrix LABoratory'

Permalänk
Medlem

Hur man itererar igenom en matris (radvis eller kolumnvis) när man räknar kan ha en enorm inverkan på hastigheten pga cachemissar i ena fallet som inte uppstår i andra. Det beror på hur raderna respektive kolumnerna är lagrade i minnet.
Kanske råkar du iterera i "fel" riktning ?

Andra saker att tänka på kan vara att det ibland kan gå mycket snabbare om antalet rader och kolumner är en jämn 2-potens.

Visa signatur

Namn : Jesper | Ålder : 45 | In-game namn : iller
Yrke : Matematisk modellerare (finansiell matematik), mjukvaruutvecklare för risksystem.
Utbildning : Doktor i matematik + en del mat-stat, numme och IT-relaterat.

Permalänk
Entusiast
Skrivet av mix_room:

En typisk matlab fråga: du kör inte en massa for-loops? Dessa är ju Matlab känd för att vara riktigt långsam på.
Det låter som om du skulle kunna ha en hel massa for-loopar som är nästlade i varandra.
Vectorisera! Kom ihåg att Matlab står för 'MATrix LABoratory'

Jag har en for-loop som ligger under en while-loop. For-loopen tugger igenom alla kollumner i matrisen från ena sidan till andra en gång och sedan kollar while-loopen efter konvergens. Det är alla loopar som är nästlade. Har lite andra för att sätta upp lite matriser som indata men de körs enbart en gång.

Skrivet av JesperT:

Hur man itererar igenom en matris (radvis eller kolumnvis) när man räknar kan ha en enorm inverkan på hastigheten pga cachemissar i ena fallet som inte uppstår i andra. Det beror på hur raderna respektive kolumnerna är lagrade i minnet.
Kanske råkar du iterera i "fel" riktning ?

Andra saker att tänka på kan vara att det ibland kan gå mycket snabbare om antalet rader och kolumner är en jämn 2-potens.

Har du lite mer information om detta? Just nu itererar jag över kolumnerna så i varje loop så räknas en ny kolumn ut. Skulle det hjälpa om jag helt enkelt transponerade hela alltet?

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24

Permalänk
Medlem
Skrivet av Zotamedu:

Jag har en for-loop som ligger under en while-loop. For-loopen tugger igenom alla kollumner i matrisen från ena sidan till andra en gång och sedan kollar while-loopen efter konvergens. Det är alla loopar som är nästlade. Har lite andra för att sätta upp lite matriser som indata men de körs enbart en gång.

Har du lite mer information om detta? Just nu itererar jag över kolumnerna så i varje loop så räknas en ny kolumn ut. Skulle det hjälpa om jag helt enkelt transponerade hela alltet?

Cache prefetching kallas det. Jag minns inte vilken ordning matlab vill ha det i men det kan hjälpa att byta plats på looparna. Bakgrunden ligger i att programmet hämtar in hela cachelines från RAMet (ungefär 64 Byte) om du går i fel riktning hämtas fel data till cachen och du får cachemisses varje iteration. Dock brukar inte det påverka prestandan mer än några 100% typ men tråden hamnar inte i sleep så det borde inte minska prestandan till de där 20% du såg. Det tror jag snarare har att göra med allokering som allokeras om och om igen i nån loop. Tänk på att vissa operationer som matlab inte modifierar datan utan skapar resultatet i en ny matris som sedan blir tillbaka kopierad. (funktionsanrop kan vara en källa till sådant).

Permalänk

Bara för att eliminera alla "du har väl startat om datorn"-lösningar. Det är ingen del där som går att ersätta med en matris-multiplikation?

Permalänk
Medlem

Nu vet jag inte riktigt vilket sorts problem du försöker lösa, men som jag ser mass-balans i celler kan du kanske prova med följande:
Jag antar att du har massändringen i varje cell som funktion av cellens nuvarande massa, massändringen står i matris A. Dvs A = f(M). Sedan räknar du ut hur mycket som kommer till från grannar. Nu får du en ny massa,

A = rand(3,3) % A = rand(n,m) % A_ny = summa av alla grannar: (A_ny(1,1) = A(1,2) + A(2,1), A_ny(2,2) = A(1,2)+A(2,1)+A(1,3)+A(3,1)) rowX = [0 1 0; 1 0 1; 0 1 0]; % diag(ones(n-1,1),-1)+diag(ones(n-1,1),1) rowY = [0 1 0; 1 0 1; 0 1 0]; % diag(ones(m-1,1),-1)+diag(ones(m-1,1),1) % för större matriser while delta(A_ny) < eps A_ny = rowX*A + A*rowY; M = A_ny - A; A = f(M); end %end-while

Det tar bort en for-loop.

Permalänk
Medlem
Skrivet av Zotamedu:

Jag har en for-loop som ligger under en while-loop. For-loopen tugger igenom alla kollumner i matrisen från ena sidan till andra en gång och sedan kollar while-loopen efter konvergens. Det är alla loopar som är nästlade. Har lite andra för att sätta upp lite matriser som indata men de körs enbart en gång.

Minnet ligger lagrat row-major. Så det är bättre om du transponerar problemet och kör rad för rad, sen transponerar tillbaka såklart.
Som du vet nu är for-loopar döden för prestanda i matlab. Om du istället kör Jacobi iterationer (har jag för mig att det heter), så kan du använda matrisoperationer istället. Långsammare konvergens, men blir nog snabbare i praktiken.

För en itereration av exempelvis laplace-ekvationen kan man skriva så här, helt utan loopar:

C_new(2:end-1,2:end-1) = ( C(1:end-2, 2:end-1) + C(3:end, 2:end-1) + C(2:end-1, 1:end-2) + C(2:end-1, 3:end) ) * 0.25;

Sjukt mkt snabbare. Alternativt, skriv en C-funktion för GS-iterationssteget och anropa från matlab (mex).

Permalänk
Entusiast
Skrivet av mix_room:

Nu vet jag inte riktigt vilket sorts problem du försöker lösa, men som jag ser mass-balans i celler kan du kanske prova med följande:
Jag antar att du har massändringen i varje cell som funktion av cellens nuvarande massa, massändringen står i matris A. Dvs A = f(M). Sedan räknar du ut hur mycket som kommer till från grannar. Nu får du en ny massa,

A = rand(3,3) % A = rand(n,m) % A_ny = summa av alla grannar: (A_ny(1,1) = A(1,2) + A(2,1), A_ny(2,2) = A(1,2)+A(2,1)+A(1,3)+A(3,1)) rowX = [0 1 0; 1 0 1; 0 1 0]; % diag(ones(n-1,1),-1)+diag(ones(n-1,1),1) rowY = [0 1 0; 1 0 1; 0 1 0]; % diag(ones(m-1,1),-1)+diag(ones(m-1,1),1) % för större matriser while delta(A_ny) < eps A_ny = rowX*A + A*rowY; M = A_ny - A; A = f(M); end %end-while

Det tar bort en for-loop.

Skrivet av Mikael07:

Minnet ligger lagrat row-major. Så det är bättre om du transponerar problemet och kör rad för rad, sen transponerar tillbaka såklart.
Som du vet nu är for-loopar döden för prestanda i matlab. Om du istället kör Jacobi iterationer (har jag för mig att det heter), så kan du använda matrisoperationer istället. Långsammare konvergens, men blir nog snabbare i praktiken.

För en itereration av exempelvis laplace-ekvationen kan man skriva så här, helt utan loopar:

C_new(2:end-1,2:end-1) = ( C(1:end-2, 2:end-1) + C(3:end, 2:end-1) + C(2:end-1, 1:end-2) + C(2:end-1, 3:end) ) * 0.25;

Sjukt mkt snabbare. Alternativt, skriv en C-funktion för GS-iterationssteget och anropa från matlab (mex).

Jag har inte satt mig in så mycket djupare i lösningen men det jag fått höra av min handlerade, som jobbat i många år med den här typen av problem, är att det är fullt möjligt att ställa upp mitt problem som ett linjärt ekvationssystem och lösa det rakt av men att det inte är praktiskt när antalet celler blir stort. Just nu kör jag i en dimension och använder mellan 10 och 100 celler för att det är lätt att få en överblick. När det sedan blir i tre dimensioner med miljontals celler så klarar Matlab tydligen inte av det längre. Så det finns en tanke med att köra iterativt förutom vissa pedagogiska anledningar.

Jag ska experimentera lite med att transponera och se vad som händer. Det finns egentligen ingen anledning att ställa upp det på ena eller andra sättet som det ser ut nu mer än att jag började. Det lär dock bli annorlunda senare i 3D då jag kommer behöva räkna med en matris i 4D. Hur vill Matlab ha det då?

Visa signatur

Q9450, HD4850, 8 GB DDR2 800 MHz, 3x750 GB, Antec 300, Dell 2408WFP, U2410, Qnap TS-419p+ 4x2 TB Samsung F4, Asus UL30A-QX056V, Logitech Z-680, Sennheiser HD380pro, M-Audio FastTrack Pro, Ibanez sa160qm, Ibanez TB 15R, Zoom 505II, Ibanez GSR 200, Ibanez SW 35, Cort AC-15, Squier SD-3 BBL, Yamaha PSR 270, Røde NT1-A, Nikon D200, Nikkor 18-70/3,5-4,5, 70-300VR, 50/1,8, 28/2,8, Tamron 17-50/2,8, 90/2,8, Sigma 30/1,4, SB-800, SB-25, SB-24