jabbalizerMedlem sedan jan. 2001134 inlägg
Jag har precis börjat intressera mig för C++. Kör i Windows XP, och använder Borland 5.5 som kompilator. Provade VS.NET också för att jämföra, och det var ju både positivt och negativt. Ett av programmen körde 50% "fortare", men ett annat gick motsvarande långsammare.
Nu vill jag gärna veta vad som funkar bäst om man vill snabba upp sina program. De två jag håller på med just nu är hårt rekursiva, och räknar en del på tal i arrayer.
1. vilket är det snabbaste sättet att slumpa fram ett tal. Detta gör jag nämligen 7 ggr på varje nivå i rekursionen på sådant vis att varje rekursivt anrop ska anropa sig själv sannolikt två gånger(av 7 möjliga).
Som det ser ut nu sä sätter jag seed en gång innan jag kör igång:
srand( (unsigned)time( NULL ) );
..och sen anropar jag:
rand()
varje gång.
Jag antar att det här sättet inte är "riktig slh" då väl rand hämtar talen från en ändlig lista, men det är inte det som är det viktiga.
2. Jag har hört att man inte ska räkna med char/unsigned char.
Varför ska man inte det? Borde det inte gå snabbare eller åtminstone kräva mindre minne?
3. Läste någonstans att:
int A = B+C*8;
borde skrivas:
int A = C;
A *=8;
a+= B;
för att undvika att temporära objekt eller variabler skapas. Detta skulle visst snabba upp? Men frågan är om den där texten är gammal, och om inte Borland & VS.NET's kompilatorer "vet" detta?
4. Läste också att man borde föredra:
A += B;
före
A = A + B;
av typ samma anledning. Kan det ligga något i det?
5. Om man ser från ett rekursivt perspektiv: Antag att det i den rekursiva funktionen används en int t.ex. Kan man tjäna något på att deklarera den globalt, alltså utanför den rekursiva funktionen? Sparar man tid för att man inte måste ta minnesplats åt den 4 miljoner gånger i metoden, eller blir det långsammare av någon anledning?
6. En rekursiv funktion som gör beräkningar i globala arrayer eller matriser: Finns det något snabbare sätt än att låta arrayerna/matriserna vara globala? Typ nåt avancerat sätt att använda pekare (fast arrayer och matriser är väl pekare till minnesplatser). Skulle man ha nån nytta av att i stället skicka med dessa i varje metodanrop?
Till sist: känner ni till några andra knep för att snabba upp saker och ting så är jag mycket tacksam =)
PeWMedlem sedan juni 20006 839 inlägg
2. Verkar inte rimligt. Vad det gäller hastighet är det ingen skillnad, men en char tar mindre utrymme och en vits med det kan vara att få plats med så mycket som möjligt i lokala variabler m.h.a cpuns cache. På en modern x86 är det dock nog ingen skillnad mha stor och effektiv cache.
3 & 4. Nej inte generellt sett, kompilatorn översätter till samma instruktioner. Har ingen inverkan på minnet eller hastighet.
5 & 6. Nä. En global variabel tar längre tid att accessa eftersom den hamnar utanför "scope" eller det minnesutrymme som ligger i cache (vilket swappas mot RAM, vilket tar tid). Att använda pekare hjälper väl inget. Men jag ser inget annat sätt när det gäller arrays eftersom de inte kopieras in i stacken. Såvida du inte explicit gör det manuellt. Å andra sidan tar ett flitigt stackanvändande tid det med, så det är en avvägningsfråga.
NickemannenMedlem sedan aug. 20003 524 inlägg
5 & 6. Nä. En global variabel tar längre tid att accessa eftersom den hamnar utanför "scope" eller det minnesutrymme som ligger i cache (vilket swappas mot RAM, vilket tar tid). Att använda pekare hjälper väl inget. Men jag ser inget annat sätt när det gäller arrays eftersom de inte kopieras in i stacken. Såvida du inte explicit gör det manuellt. Å andra sidan tar ett flitigt stackanvändande tid det med, så det är en avvägningsfråga.
Jag hade fått för mig att om man skickar pekare som parameterar istället för variabler som innehåller datastrukturer så skulle man vinna prestanda och minne eftersom den aktuella datastrukturen inte behöver kopieras för att läggas på den anropade funktionens stack.
Men jag kanske har fel.
PeWMedlem sedan juni 20006 839 inlägg
Det är som sagt en avvägningsfråga där fler parametrar vägs in. Som cpu, arkitektur, storlek på stack, minnesblock m.m. Men generellt så är det ingen prestandahöjare att adressera ett minnesutrymme (pekare) som ligger utanför det som ligger i cache (läs globalt i det här fallet) eftersom vid varje adressering swappas hela minnesblocket ut mot det där pekaren pekar. Blir en hel del swappande mao. Arrays kopieras inte in på stacken om du inte gör det explicit (lägger in element för element). Men på moderna PC:s med en gigantisk cache är problemet inte lika stort som på exempelvis ett litet embedded system.
ToonsterMedlem sedan feb. 20001 546 inlägg
Du kanske redan gjort detta, men...
Det finns massor av inställningar för hur kompileringen ska ske osv. Bla. i Borlands projektinställningar, så kan man ange om det ska vara realease och debug osv. Även hur koden ska kompileras och till vilken processorfamilj.
Naturligtvis ska man optimera sin kod om det är nödvändigt prestandamässigt redan vid programmeringen, men det är minst lika viktigt att kompileringen utförs maximalt.
NickemannenMedlem sedan aug. 20003 524 inlägg
PeW skrev:
Det är som sagt en avvägningsfråga där fler parametrar vägs in. Som cpu, arkitektur, storlek på stack, minnesblock m.m. Men generellt så är det ingen prestandahöjare att adressera ett minnesutrymme (pekare) som ligger utanför det som ligger i cache (läs globalt i det här fallet) eftersom vid varje adressering swappas hela minnesblocket ut mot det där pekaren pekar. Blir en hel del swappande mao. Arrays kopieras inte in på stacken om du inte gör det explicit (lägger in element för element). Men på moderna PC:s med en gigantisk cache är problemet inte lika stort som på exempelvis ett litet embedded system.
Okej, så om jag har fattat det rätt då så är användningen av pekare påväg bort då?
Kan vara därför vi lärde oss att programmera i C för inbyggda system :)
Sang-draxMedlem sedan juli 2002570 inlägg
3 & 4. Ja, om du använder klasser (typ. BigInt) och inte de inbyggda datatyperna så spelar det roll. Det är möjligt (men mycket komplicerat) att skriva klasser som inte skapar temporärer vid räkningar som i dina exempel.
Sang-draxMedlem sedan juli 2002570 inlägg
Nickemannen skrev:
Okej, så om jag har fattat det rätt då så är användningen av pekare påväg bort då?
<SangDrax teori>
Det finns tre stadier i en C++-programerares utveckling:
- Du tycker pekare är svårt och undrar ved pekararitmetik egentligen är bra till.
- Du har fattat pekare och tycker de är mycket, mycket bra. Du känner dig tillfreds med att kunna programmera med pekare.
- Du har insett att pekare knappt behövs i C++. STL är mycket bra!
</SangDrax teori>