42 votes

L'alignement est-il vraiment important pour les performances en C ++ 11?

L'alignement est-il vraiment important pour les performances en C ++ 11?

Dans le livre de Stroustrup, il est conseillé de classer les membres dans une structure commençant du plus grand au plus petit. Mais je me demande si quelqu'un a fait des mesures pour voir si cela fait une différence et si cela vaut la peine de penser à l'écriture de code.

91voto

Ben Voigt Points 151460

L'alignement des questions non seulement pour la performance, mais aussi pour l'exactitude. Certaines architectures échoue avec un processeur piège si les données ne sont pas correctement alignés, ou accéder au mauvais emplacement de la mémoire. Sur d'autres, l'accès à des variables non alignés est divisé en plusieurs accès et bitshifts (souvent à l'intérieur du matériel, parfois par des OS piège gestionnaire), la perte de l'atomicité.

Les conseils pour trier les membres par ordre décroissant de la taille optimale de l'emballage / un minimum d'espace gaspillé par le rembourrage, pas de l'alignement ou de la vitesse. Les membres seront alignées correctement n'importe quel ordre vous en faire la liste, sauf si vous demandez de la non-conforme de mise en page avec des pragmas (c'est à dire la non-portable #pragma pack) ou de mots clés. Bien que la taille totale de la structure est affectée par le rembourrage et affecte également la vitesse, souvent il y a une autre commande qui est optimal.

Pour de meilleures performances, vous devriez essayer d'obtenir les membres qui sont utilisés ensemble dans la même ligne de cache, et les membres qui sont accessibles par les différents fils de discussion dans différentes lignes de cache. Parfois, cela signifie beaucoup de rembourrage pour obtenir un cross-thread variable partagée seul dans sa propre ligne de cache. Mais c'est mieux que de prendre un gain de performance de faux partage.

10voto

Dariusz Points 8058

Juste pour ajouter de Ben grande réponse:

Définir les membres de la structure dans le même ordre qu'ils sont par la suite accessible dans votre application permettra de réduire les défauts de cache et peut-être augmenter les performances. Cela fonctionne à condition que la totalité de la structure ne rentre pas dans le cache L1.

D'autre part, de commander les membres de la plus grande à la plus petite, peut réduire l'ensemble de l'utilisation de la mémoire, qui peut être importante lors de stocker un tableau de petites structures.

Supposons que pour une architecture (je ne les connais pas bien, je pense que ce serait le cas pour les paramètres par défaut de 32 bits gcc, quelqu'un va me corriger dans les commentaires) cette structure:

struct MemoryUnused {
  uint8_t val0;
  uint16_t val1;
  uint8_t val2;
  uint16_t val3;
  uint8_t val4;
  uint32_t val5;
  uint8_t val6;
}

prend 20 octets en mémoire, alors que ceci:

struct MemoryNotLost {
  uint32_t val5;
  uint16_t val1;
  uint16_t val3;
  uint8_t val0;
  uint8_t val2;
  uint8_t val4;
  uint8_t val6;
}

Prendra 12. C'est 8 octets perdus en raison du rembourrage, et c'est une augmentation de 67% de la taille de la smallers struct. Avec un grand nombre de ces structures, le gain serait important, tout simplement parce que la quantité de mémoire utilisée, va diminuer la quantité de défauts de cache.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X