void somefunction(void) {
vector3f_t result;
vector3f_t a = {1.0f, 2.0f, 3.0f};
vector3f_t b = {3.0f, 2.0f, 1.0f};
/* Hur jag vill ha det */
result = add_vector(a, b);
}
i .h filen:
typedef struct
{
float x, y, z;
} vector3f_t;
static inline vector3f_t add_vector(vector3f_t a, vector3f_t b)
{
vector3f_t temp;
temp.x = a.x + b.x;
temp.y = a.y + b.y;
temp.z = a.z + b.z;
return temp;
}
Frågan är då, är kopilatorn (GCC) smart nog att inse att den inte behöver kopiera strukturen fram å tillbaka en massa i onödan? Då allt data finns där redan.
Utan använder den direkt i koden, som om jag hade implementerat det som ett macro.
Någon som vet? Har kollat på disassemblyn som skapas, och är inte så jätte hajj på Cortex-M4 assembler tyvärr.
Senast redigerad av Korken 12 maj 2014, 19:53:18, redigerad totalt 1 gång.
Min egna erfarenhet säger att GCC brukar vara bra på att optimera, men det är antagligen helt olika beroende vilket instruktionsset man bygger för.
Du kan ju hjälpa den lite genom att låta argumenten vara pekare till const-strukturer, eller åtminstone återanvända ett av argumenten och addera den ena till den andra.
Vid inline borde den nog optimera vettigt. I fall där man inte kan köra med inline kan man ju köra argument med referens istället. Då blir det mindre kopierande...
Tackar för svaren!
Jag är medveten om att det är bäst att köra med referenser till strukturerna, men gillar mer mitt skrivsätt.
Jag hoppas bara att det optimerar vettigt, men ska nog grotta ner mig i ASM koden å se vad den har för sig.
för metoder där utdata _enbart_ beror på inskickad data (det innebär att du _inte_ får använda det där parametrarna är pekare, om du derefererar dem.. inte heller använda nån global data etc).
Min erfarenhet av GCC för ARM är att den optimerar bra.
Jag satt för några år sedan och grottade ner mig i assembler för att uppdatera en display (data/clk/hsync/vsync) och var ganska mallig över min insats. Fjorton instruktioner. Testade att kompilera motsvarigheten skriven i C, utan grubblerier. Tretton av mina fjorton instruktioner, en var onödig och efter lite grubblande fattade jag varför.
Däremot tycker jag att man ska läsa genererad assembler emellanåt. Av två skäl, man lär sig en hel del och ibland hittar man uppenbara dumheter.
Jag har liknande erfarenhet, optimeringen i moderna kompilatorer är extremt bra. Det är oftast bara om man VET att man kan förenkla som man kan handoptimera bättre.
Precis, jag gillar verkligen skrivsättet tex vector3f_t a = vector_cross(b, c);
Där vector_cross är inline kod. Det blev hur fin assembler som helst av det
Såg att du skrev att du kikat på assemblerkoden ... det borde inte vara så klurigt att förstå för dig vad som händer i just det avsnittet du är intresserad av. Du kan ju om möjligt reducera koden till just ditt exempel så att du inte får en massa brus runt det du faktiskt är intresserad av.
Ett tips om du är nyfiken på att se vad gcc kör av din kod så kompilera med flaggan -S
gcc -S -o asm_output.s code.c
då genereras assemblerkod. Gör samma sak fast med -O2 eller vad du nu använder för flaggor så kan du direkt jämföra vad för skillnader som blir. Är det viktigt med prestanda och hur kompilatorn beter sig så ska man inte gissa/tro vad kompilatorn gör utan glutta på vad den faktiskt gör och det kan faktiskt vara så att man tvingas lära sig några assembler-instruktioner.
monstrum skrev:Min egna erfarenhet säger att GCC brukar vara bra på att optimera, men det är antagligen helt olika beroende vilket instruktionsset man bygger för.
Olika typer av optimeringar torde väl vara allt mellan helt oberoende till helt beroende av instruktionsuppsättningen/arkitekturen man kompilerar för.
Sådant som att optimera bort redundant kod torde ske på en plattformsoberoende nivå.
Utan att veta så antar jag att GCC är bra för de större plattformar som GCC används till idag, ungefär. Vad jag förstått så finns/fanns det väl kompilatorer som är lite bättre specifikt för vissa plattformar, t.ex. så sägs väl GCC inte ha varit helt i toppklass för Motorola 68k, om jag fattat rätt så var det något med att GCC inte är så jättebra på att hantera processorer som har en begränsad men ändå hyggligt stor klase register för data respektive för adresser, istället för helt universella register (eller ytterst få register).
Vi hade ett projekt för ATmega32, eller möjligen 16. Spelar roll.
Allmän visdom ungefär 2007 var att IAR genererade mycket bättre kod för den processorn. Vi gjorde ett test, och ja, IAR var ungefär 10% bättre.
Kan vara av visst intresse om man ligger nära gränsen till en större processor men det blir rätt mycket kisel för priset på en IAR-kompilator.
Nu var det här ett projekt med mycket stora volymer men projektledningen valde ändå GCC. Vi var inte intresserade av IARs krångel med licenser.
Nu i 4.9 av GCC så kommer nog LTO fungera som det ska också och när jag testade den (i 4.8 ) så minskade kodstorleken med ca 20%.
Kan vara värt att kolla på.