Compilers

Waarom kan de compiler in de bovenstaande functie de optimalisatie waarbij het lezen van *b buiten de lus wordt gebracht niet zonder meer uitvoeren?

void add(int *a, int *b, int n) {
    for (int i = 0; i < n; i++)
        a[i] += *b;
}
  1. A*b is een geheel getal, dus verplaatsing buiten de lus verlaagt de precisie van de waarde
  2. Ba en b kunnen naar dezelfde plaats wijzen, en door het schrijven naar a[i] kan *b veranderen
  3. CVoor functies die pointers als argument nemen, is optimaliseren door de compiler volgens de regels helemaal verboden
Antwoord en toelichting tonen

Antwoord: B. a en b kunnen naar dezelfde plaats wijzen, en door het schrijven naar a[i] kan *b veranderen

Op het eerste gezicht verandert *b in de lus niet en lijkt eenmaal lezen voldoende. Als de aanroeper echter een pointer doorgeeft waarbij b naar een element van a wijst, bijvoorbeeld add(x, &x[3], n), verandert de waarde van *b door het schrijven naar a[3]. De compiler kan deze mogelijkheid (aliasing) niet uitsluiten en genereert daarom code die telkens opnieuw leest. In C kan worden geoptimaliseerd door pointers met restrict te markeren en zo te beloven dat ze naar verschillende plaatsen wijzen. Het is geen kwestie van precisie, en optimalisatie is niet verboden.

Dit onderwerp oefenen Naar de onderwerppagina

Meer vragen over Compilers

  1. Welke combinatie van wat knopen en bogen voorstellen is juist bij de methode van het kleuren van een interferentiegraaf bij registertoewijzing in een compiler?
  2. Wat gebeurt er met de gegenereerde code als bij registertoewijzing een "spill" optreedt?
  3. Wat is het belangrijkste doel van instructieplanning (instruction scheduling) in een compiler?
  4. Welk effect heeft het toepassen van tail call optimization op de laatste recursieve aanroep van de bovenstaande functie?
  5. Welk verschil tussen een compiler en een interpreter is juist?

Vergelijkingen bij dit onderwerp