Cela peut sembler évident, mais les ordinateurs n'exécutent pas de formules , ils exécutent du code , et la durée de cette exécution dépend directement du code qu'ils exécutent et seulement indirectement du concept que le code implémente. Deux morceaux de code logiquement identiques peuvent avoir des caractéristiques de performances très différentes. Certaines raisons susceptibles de se produire spécifiquement dans la multiplication matricielle:
- Utilisation de plusieurs threads. Il n'y a presque pas de CPU moderne qui ne possède pas plusieurs cœurs, beaucoup en ont jusqu'à 8, et les machines spécialisées pour le calcul haute performance peuvent facilement en avoir 64 sur plusieurs sockets. L'écriture de code de manière évidente, dans un langage de programmation normal, n'en utilise qu'un seul . En d'autres termes, il peut utiliser moins de 2% des ressources informatiques disponibles de la machine sur laquelle il fonctionne.
- Utilisation d'instructions SIMD (de manière confuse, cela est aussi appelé "vectorisation" mais dans un sens différent de celui des citations de texte dans la question). Essentiellement, au lieu de 4 ou 8 instructions arithmétiques scalaires, donnez au CPU une instruction qui exécute l'arithmétique sur 4 ou 8 registres en parallèle. Cela peut littéralement faire des calculs (lorsqu'ils sont parfaitement indépendants et adaptés au jeu d'instructions) 4 ou 8 fois plus rapidement.
- Faire un usage plus intelligent du cache . Les accès en mémoire sont plus rapides s'ils sont cohérents dans le temps et dans l'espace , c'est-à-dire que les accès consécutifs se font vers des adresses proches et lorsque vous accédez deux fois à une adresse, vous y accédez deux fois de suite rapidement plutôt qu'avec une longue pause.
- Utilisation d'accélérateurs tels que les GPU. Ces appareils sont des bêtes très différentes des processeurs et leur programmation efficace est une forme d'art à part entière. Par exemple, ils ont des centaines de cœurs, qui sont regroupés en groupes de quelques dizaines de cœurs, et ces groupes partagent des ressources - ils partagent quelques Kio de mémoire beaucoup plus rapide que la mémoire normale, et lorsqu'un cœur du groupe exécute un
if
déclaration tous les autres membres de ce groupe doivent l'attendre.
- Répartissez le travail sur plusieurs machines (très important dans les superordinateurs!), Ce qui introduit un énorme ensemble de nouveaux maux de tête mais peut, bien sûr, donner accès à des ressources informatiques beaucoup plus importantes.
- Des algorithmes plus intelligents. Pour la multiplication matricielle, l'algorithme simple O (n ^ 3), correctement optimisé avec les astuces ci-dessus, est souvent plus rapide que les sous-cubes pour des tailles de matrice raisonnables, mais parfois ils gagnent. Pour des cas particuliers tels que des matrices clairsemées, vous pouvez écrire des algorithmes spécialisés.
Beaucoup de gens intelligents ont écrit du code très efficace pour les opérations d'algèbre linéaire courantes , en utilisant les astuces ci-dessus et bien d'autres et généralement même avec des astuces stupides spécifiques à la plate-forme. Par conséquent, transformer votre formule en une multiplication matricielle puis implémenter ce calcul en appelant dans une bibliothèque d'algèbre linéaire mature bénéficie de cet effort d'optimisation. En revanche, si vous écrivez simplement la formule de manière évidente dans un langage de haut niveau, le code machine qui sera finalement généré n'utilisera pas toutes ces astuces et ne sera pas aussi rapide. Cela est également vrai si vous prenez la formulation matricielle et l'implémentez en appelant une routine de multiplication matricielle naïve que vous avez écrite vous-même (encore une fois, de manière évidente).
Faire du code rapidement demande du travail , et souvent beaucoup de travail si vous voulez cette dernière once de performance. Étant donné que de nombreux calculs importants peuvent être exprimés sous la forme d'une combinaison de deux opérations d'algèbre linéaire, il est économique de créer un code hautement optimisé pour ces opérations. Mais votre cas d'utilisation spécialisé unique? Personne ne se soucie de cela, sauf vous, donc l'optimisation de tout cela n'est pas économique.