4

Je suis impatient de comprendre comment optimiser le nombre d'opérations que je peux obtenir sur mon CPU. Je fais un simple programme de multiplication de matrices, et j'ai un processeur de Skylake. Je regardais la page wikipedia pour les informations de flops sur cette architecture, et j'ai des difficultés à le comprendre. D'après ce que je comprends, les instructions FMA autorisent les entrées FP à 3 voies? Et permettre de mélanger entre ajoute et multiplie entre eux. Mais que se passe-t-il quand j'ajoute seulement deux flotteurs? Le multiplie-t-il simplement par un? Puis-je ajouter 3 flotteurs en 1 cycle, ou sera-t-il divisé? J'ai vu que le skylake, a 32 FLOPs/cycle pour les entrées de précision simple, mais quelle est la signification de "deux 8-wide FMA instructions"?Comprendre les performances des instructions FMA

Nous vous remercions à l'avance pour les explications

+1

Cette question devient plus intéressante si vous comparez Haswell et Skylake. Haswell ne peut faire qu'un AVX par cycle d'horloge mais deux opérations FMA par cycle d'horloge. Cela signifie que vous pouvez doubler votre débit d'ajout en utilisant deux opérations FMA en multipliant par 1.0. OTH, la latence pour FMA est de 5 alors que l'addition est de trois sur Haswell donc vous devez utiliser 10 accumulateurs parallèles pour obtenir le débit maximum AVEC FMA alors que vous n'avez besoin que de 3 avec addition. Sur l'addition Skylake et FMA ont la même latence et le débit donc il n'y a aucune raison d'utiliser FMA pour l'addition. –

Répondre

5

FMA calcule ± a * b ± c en une seule opération, avec une erreur d'arrondi unique. C'est ce que ça fait, rien d'autre. Le calcul de a + b + c ne peut pas être effectué en utilisant une instruction FMA; vous avez besoin de deux opérations ADD dépendantes pour cela. En fonction du compilateur, vous devrez peut-être activer une option de compilateur pour autoriser l'utilisation d'instructions FMA, car elles ne donnent pas de résultats identiques à multiplier suivi de l'option add. Et vous devrez peut-être réorganiser votre code dans certains cas, par exemple un b + c d + e sera calculé comme x = a b; y = FMA (c, d, x), z = y + e mais e + a b + c * d sera calculé comme x = FMA (a, b, e); z = FMA (c, d, x). Le calcul de l'opération de base d'une FFT peut être effectué avec huit opérations en virgule flottante et peut être réécrit en 10 opérations en utilisant quatre FMA et deux autres opérations. "Deux instructions FMA à 8 largeurs" signifie qu'il peut exécuter des instructions FMA avec deux registres vectoriels de 256 bits contenant chacun 8 flotteurs, et deux d'entre eux dans le même cycle.

+0

Explication très claire. Merci: D –

+0

Une façon de faire comprendre au compilateur qu'il est acceptable d'utiliser l'instruction d'assemblage fusionné multiplier-ajouter est d'utiliser les fonctions 'fma',' fmaf', 'fmal' dans le code source, mais si le compilateur est configuré pour générer un code rétrocompatible et pour respecter la différence entre fma et "' * 'suivi de '+' ", ces fonctions seront compilées comme des suites coûteuses de nombreuses instructions, soit comme https://sourceware.org /bugzilla/attachment.cgi?id=6017 ou comme https://sourceware.org/ml/libc-hacker/2010-10/msg00005.html –

+0

Ce serait génial s'il y avait un mode simple d'arrondi rapide 'a + b + c' instruction. Cela rendrait l'addition «double-double» rapide, ce qui est actuellement beaucoup plus lent que la multiplication «double-double» avec FMA. http://stackoverflow.com/a/30643684/2542702 –