2010-03-29 9 views
2

J'utilise souvent des références pour simplifier l'apparence de code:optimisation du compilateur de références

vec3f& vertex = _vertices[index]; 

// Calculate the vertex position 
vertex[0] = startx + col * colWidth; 
vertex[1] = starty + row * rowWidth; 
vertex[2] = 0.0f; 

Est-ce compilateurs reconnaître et d'optimiser cela, il est donc essentiellement les suivantes?

_vertices[index][0] = startx + col * colWidth; 
_vertices[index][1] = starty + row * rowWidth; 
_vertices[index][2] = 0.0f; 
+2

Pourquoi pensez-vous que la deuxième version est «plus optimisée» que la première? Vous pourriez découvrir que le premier bloc de code peut effectivement être plus rapide que le second dans des circonstances différentes (surchargé '[]', la référence étant implémentée comme un pointeur dans un registre ... –

+2

Il semblerait en effet plus logique de demander si le second extrait peut être optimisé au premier (élimination de sous-expression commune, je pense). – visitor

Répondre

8

Oui. C'est une optimisation de base que tout compilateur moderne (et même ancien) fera.

En fait, je ne pense pas qu'il soit vraiment précis d'appeler que vous avez écrit une optimisation, puisque la façon simple de traduire cela en assembly implique un stockage à l'adresse _vertex, plus index, plus {0, 1,2} (multiplié par les tailles appropriées pour les choses, bien sûr).

En général cependant, les compilateurs modernes sont incroyable. Presque toute l'optimisation que vous pouvez imaginer sera mise en œuvre. Vous devriez toujours écrire votre code d'une manière qui met l'accent sur la lisibilité, à moins que vous sachiez que d'une manière a des avantages significatifs de performance pour votre code.

Comme un exemple simple, le code comme ceci:

int func() { 
    int x; 
    int y; 
    int z; 
    int a; 

    x = 5*5; 
    y = x; 
    z = y; 
    a = 100 * 100 * 100* 100; 

    return z; 
} 

sera optimisé à ceci:

int func() { 
    return 25 
} 

De plus, le compilateur inline également la fonction de sorte qu'aucun appel est en fait. Au lieu de cela, partout 'func()' apparaîtra sera simplement remplacé par '25'.

Ceci est juste un exemple simple. Il y a beaucoup plus d'optimisations complexes qu'un compilateur moderne implémente.

+5

+1 pour "Vous devriez toujours écrire votre code d'une manière qui met l'accent sur la lisibilité". N'essayez pas la micro-optimisation de cette manière à moins que vous ayez * profilé * votre code et * mesuré * que vous ayez un problème * à ce stade *. Cela étant dit, l'utilisation par le PO d'une référence pour se débarrasser d'un index dans les expressions suivantes pourrait être considérée comme une "optimisation de la lisibilité" en soi, donc je suis content. ;-) – DevSolar

+0

Le "amazingness" dépend en réalité du compilateur et du matériel. – n0rd

3

Les compilateurs feront même plus de choses intelligentes que cela. Peut-être qu'ils vont faire

vec3f * vertex = _vertices[index]; 

*vertex++ = startx + col * colWidth; 
*vertex++ = starty + row * rowWidth; 
*vertex++ = 0.0f; 

ou même d'autres variations ...

+0

L'exécution naïve de celui-là serait presque certainement plus lente. Vous venez de créer des dépendances entre les trois affectations lorsqu'elles n'existaient pas auparavant. – jalf

+0

Cela me semble aussi rapide. Les dépendances peuvent prendre du temps mais il existe des calculs supplémentaires et des écritures de mémoire qui peuvent être entrelacées. – MSalters

2

Selon les types de variables, ce que vous avez décrit est une pessimisation.

Si vertices est un type de classe, votre formulaire d'origine effectue un seul appel à operator[] et réutilise la référence renvoyée. Votre deuxième formulaire fait trois appels distincts. On ne peut pas nécessairement déduire que la référence renvoyée se rapportera au même objet à chaque fois.

Le coût d'une référence n'est probablement pas important par rapport aux recherches répétées dans l'objet original vertices. Sauf dans des cas limités, le compilateur ne peut pas optimiser (ou pessimiser) les appels de fonction supplémentaires, à moins que la modification introduite ne soit pas détectable par un programme conforme. Cela nécessite souvent la visibilité d'une définition en ligne.

Ceci est connu comme la règle "as if". Tant que le code se comporte comme si les règles de langage ont été suivies exactement, l'implémentation peut faire toutes les optimisations qu'il juge appropriées.

+0

Que se passe-t-il si 'operator []' est assez trivial, comme 'return data [index];', et est déclaré 'inline'? – Thomas

+0

@Thomas: Alors les paragraphes quatre et cinq pourraient s'appliquer. –

+0

C'est la "puissance" que je m'interroge;) – Thomas