Question

Je fais une bibliothèque vecteur / matrice. (GCC, ARM NEON, iPhone)

typedef struct{ float v[4]; } Vector;
typedef struct{ Vector v[4]; } Matrix;

Je passe des données struct comme pointeur pour éviter de dégrader les performances de la copie de données lorsque vous appelez la fonction. Donc, j'ai conçu fonction comme ceci dans un premier temps:

void makeTranslation(const Vector* factor, Matrix* restrict result);

Mais, si la fonction est en ligne, est-il une raison pour transmettre des valeurs comme pointeur pour la performance? Est-ce que ces variables copiées aussi? Que diriez-vous enregistrer et caches? J'ai essayé de redessiner la fonction comme ceci:

inline Matrix makeTranslation(const Vector factor) __attribute__ ((always_inline));

Comment pensez-vous à appeler les coûts de chaque cas?

  • I ajouté 'const' au 2 signature pour refléter des suggestions.
Était-ce utile?

La solution

Lorsque la fonction est en ligne généralement aucune copie de variables est directement impliqué dans l'appel. Les variables seront toujours déplacés et mis sur la pile parfois comme une partie normale de l'exécution, mais pas en conséquence directe de l'appel de fonction. (Lorsque vous exécutez sur des registres, certaines valeurs peuvent se mettre sur la pile, etc ... mais seulement si nécessaire.) Donc, les frais généraux de l ' « appel » disparaît essentiellement lorsqu'une fonction est inline (Pas plus la mise en place / démolissant le cadre de pile, saut inconditionnel pas plus, pas plus de poussée / paramètres pOPING).

Si vous pouvez compter sur votre attribut always_inline toujours inline la fonction, alors vous devriez pas non plus passer le vecteur par pointeur (si elle est pas modifiée). La raison en est que le passage par pointeur requiert l'adresse du vecteur soit prise, ce qui signifie que le compilateur doit veiller à ce qu'il a une adresse et donc il ne peut exister que dans les registres CPU. Cela peut ralentir les choses si elle n'est pas nécessaire, et quand vous prenez l'adresse de quelque chose que le compilateur toujours assurer qu'il a une adresse parce que le compilateur ne peut pas être sûr que l'adresse n'est pas nécessaire.

En raison du passage par pointeur, ce code aura toujours une instruction pour obtenir l'adresse de l'objet, et au moins un déréférencement pour obtenir à la valeur d'un membre. Si vous passez par valeur cela peut encore arriver, mais le compilateur peut être en mesure d'optimiser tout cela loin.

Ne pas oublier que l'utilisation excessive de inline peut augmenter considérablement la taille du code binaire du compilateur. Dans certains cas, ayant de larges segments de code (en raison des fonctions inline) peut provoquer des misses plus de cache d'instructions avec entraînera un ralentissement des performances parce que le CPU est constamment avoir à sortir à la mémoire principale pour rechercher des parties de votre programme parce que certaines d'entre elles est trop grand pour tenir dans la petite cache L1. Cela peut être particulièrement important dans les processeurs embarqués (comme l'iPhone) parce que ces processeurs ont généralement de petites caches.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top