GNT sans publicité, site mobile, fonctionnalitées exclusives...

memcpy, ATLAS et C++

Le
plagne.laurent
Bonjour à tous,

je viens de faire des mesures de perfs sur mon système linux (X86) qui
me laissent un peu songeur

Quand je fais une copy de vecteur de réels avec une simple boucle (les
resultats sont équivalent sur des pointeur C où des vecteurs STL),
j'obtiens des perfs qui sont les mêmes que si je passe par memcpy(..).
Je m'interesse en particulier aux grand vecteur (eg. size=10e6).

for (int i=0 , i <size ; i++) X[i]=Y[i]

Sur ma machine, les perfs hors cache sont +/- constantes ( +/- 50
Millions d'élements copiés par seconde)

A ce point, tout va bien et le compilo (gcc) semble faire un boulot
correct

Sauf que : Si je fais la même opération via ATLAS ( ATL_dcopy(..)),
j'obtiens une performance meilleure d'un facteur 2 (+/- 100 Millions
d'éléments copiés par seconde).

Trois questions :
1 Vous semble-t-il normal qu'une opération aussi élémentaire soit
"nativement" aussi peu optimisée ?
2 Est-il possible de modifier l'environnement pour que la version
boucle soit efficace (modif de la libc ?)
3 Je n'ai rien compris au film ?

P.S. Je développe une bibliothèque où les opérations globale sur
les vecteurs sont définies et sil'utilisateur
écrit X=Y cela appel ATLAS si la lib est installée. Mais j'ai quand
même l'impression que ce bon niveau de perf
devrait être accessible directement depuis le langage

Merci pour vos lumières !

Laurent
Lire les 11 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Marc Boyer
Le #299565
Le 07-12-2006,
Quand je fais une copy de vecteur de réels avec une simple boucle (les
resultats sont équivalent sur des pointeur C où des vecteurs STL),
j'obtiens des perfs qui sont les mêmes que si je passe par memcpy(..).


Avec quel niveau d'optimisation ?

Je m'interesse en particulier aux grand vecteur (eg. sizee6).

for (int i=0 , i <size ; i++) X[i]=Y[i]

Sur ma machine, les perfs hors cache sont +/- constantes ( +/- 50
Millions d'élements copiés par seconde)

A ce point, tout va bien et le compilo (gcc) semble faire un boulot
correct...


Et as-tu testé std::copy ?

Sauf que : Si je fais la même opération via ATLAS ( ATL_dcopy(..)),
j'obtiens une performance meilleure d'un facteur 2 (+/- 100 Millions
d'éléments copiés par seconde).


D'après le nom, elle est optimisée pour gérer des doubles.

Trois questions :
1 Vous semble-t-il normal qu'une opération aussi élémentaire soit
"nativement" aussi peu optimisée ?


Je ne considère pas que copier 1e6 doubles soit une opération
élémentaire.

2 Est-il possible de modifier l'environnement pour que la version
boucle soit efficace (modif de la libc ?)


Aucune idée, et cela n'a rien à voir avec le C++ standard, mais
avec la doc de ton compilo.

3 Je n'ai rien compris au film ?


Quelles connaissance en architecture Intel as-tu ?

P.S. Je développe une bibliothèque où les opérations globale sur
les vecteurs sont définies et sil'utilisateur
écrit X=Y cela appel ATLAS si la lib est installée. Mais j'ai quand
même l'impression que ce bon niveau de perf
devrait être accessible directement depuis le langage...


Ben, si c'était déjà dans le langage, pourquoi des gens se
seraient-ils amusé à écrire ATL_dcopy ?

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)

Laurent Deniau
Le #299564
wrote:
Bonjour à tous,

je viens de faire des mesures de perfs sur mon système linux (X86) qui
me laissent un peu songeur...

Quand je fais une copy de vecteur de réels avec une simple boucle (les
resultats sont équivalent sur des pointeur C où des vecteurs STL),
j'obtiens des perfs qui sont les mêmes que si je passe par memcpy(..).
Je m'interesse en particulier aux grand vecteur (eg. sizee6).

for (int i=0 , i <size ; i++) X[i]=Y[i]

Sur ma machine, les perfs hors cache sont +/- constantes ( +/- 50
Millions d'élements copiés par seconde)

A ce point, tout va bien et le compilo (gcc) semble faire un boulot
correct...

Sauf que : Si je fais la même opération via ATLAS ( ATL_dcopy(..)),
j'obtiens une performance meilleure d'un facteur 2 (+/- 100 Millions
d'éléments copiés par seconde).

Trois questions :
1 Vous semble-t-il normal qu'une opération aussi élémentaire soit
"nativement" aussi peu optimisée ?


'aussi peu' est peut-etre un peu exagere.

2 Est-il possible de modifier l'environnement pour que la version
boucle soit efficace (modif de la libc ?)


En faisant la meme chose que ATLAS?

Lorsque j'ai developpe la SL++ (ca remonte a 98), les problemes de
performances venaient de la gestion des caches. Blitz++ est arrive aux
memes conclusions un peu avant. Optimiser du code portable pour utiliser
au mieux le cache n'est pas trivial surtout quand les operations
balayent lineairement la memoire. Il y a en premier lieu des
considerations d'alignement des donnees comme par exemple aligner les
blocs memoire sur 64, 128 ou 256 bytes. Ensuite pour les tres gros
blocs, utiliser des pages systeme (alignement et taille). Ces
contraintes sont plus fortes que celles du langages mais reste possible
de maniere portable. Le gain peut aller jusqu'a un facteur 2.

Ensuite on passe au niveau de l'assembleur. En utilisant les proprietes
propres aux caches, les techniques de pre-chargement permettent un gain
d'encore un facteur 2. Mais ce n'est plus du tout portable. C'est tres
bien decrit et compare dans la doc des processeurs AMD (ch 5 'Cache and
Memory Optimisation' du 'Code Optimization Guide'. Il y a surement la
meme chose dans les guides d'Intel et des autres constructeurs.

Voila peut-etre ce que ATLAS fait et qui depasse le cadre de la STL.

a+, ld.

Mathias Gaunard
Le #299562
Laurent Deniau wrote:

Voila peut-etre ce que ATLAS fait et qui depasse le cadre de la STL.


Je vois pas pourquoi cela dépasserait du cadre.
Une implémentation de la bibliothèque standard n'a pas à être portable.
C'est justement l'intérêt qu'elle soit standard : chaque compilateur
peut écrire la sienne optimisée pour son compilateur.

En fait il est même difficile de distinguer compilateur et bibliothèque
standard, car le moyen le plus performant de l'implémenter et de faire
de cette bibliothèque un élément du compilateur.

Bien sûr quand le compilateur lui-même est portable, c'est assez compliqué.

Laurent Deniau
Le #299561
Mathias Gaunard wrote:
Laurent Deniau wrote:

Voila peut-etre ce que ATLAS fait et qui depasse le cadre de la STL.



Je vois pas pourquoi cela dépasserait du cadre.
Une implémentation de la bibliothèque standard n'a pas à être portable.
C'est justement l'intérêt qu'elle soit standard : chaque compilateur
peut écrire la sienne optimisée pour son compilateur.


Vous confondez portabilite hardware (qui concerne les points que je
site) et portabilite software. Je ne connais pas de vendeur de
compilateur qui souhaite specialiser son compilateur ou sa bibliotheque
pour un hardware unique, a part peut-etre Micro$oft qui en a les moyens.

En fait il est même difficile de distinguer compilateur et bibliothèque
standard, car le moyen le plus performant de l'implémenter et de faire
de cette bibliothèque un élément du compilateur.


C'est ce que fait par exemple glib avec gcc pour les points critiques.
Mais dans ce cas, le code devient tres complique, donc couteux a
modifier et maintenir.

Bien sûr quand le compilateur lui-même est portable, c'est assez compliqué.


Ben oui. D'autre part, regardez la taille du code des bibliotheques
optimisees multi-plateformes par rapport aux fonctionnalites fournies,
comme par exemple BLAS (ce qui interesse le PO). Le ratio est en general
tres faible... Pour finir, la STL n'a pas vocation a etre ultra
optimisee, mais plutot a etre largement disponible (donc comportement
standardise), stable et polyvalente.

Pour ce qui concerne le PO et le type d'optimisation qu'il cherche, je
lui recommanderait de regarder si son compilateur fourni des valarray
optimises pour les movements memoires, mais meme si c'est le cas, ca
reste dependant du compilateur.

a+, ld.


Fabien LE LEZ
Le #299535
On Thu, 07 Dec 2006 18:23:51 +0100, Mathias Gaunard :

Une implémentation de la bibliothèque standard n'a pas à être portable.
C'est justement l'intérêt qu'elle soit standard : chaque compilateur
peut écrire la sienne optimisée pour son compilateur.


Oui et non.

La STL de VC++, par exemple, peut être optimisée pour Windows, et pour
Intel 386 (voire, à la rigueur, Intel Pentium).
Il est possible qu'on puisse optimiser encore plus, avec une version
Intel Pentium (compatible tous processeurs), une version "Intel
récent", et une version "AMD récent".
(D'ailleurs, il me semble que certains logiciels, notamment de
compression ou décompression vidéo, sont fournis en trois versions.)

Pour la STL de g++, c'est plus compliqué : je vois mal l'auteur de
cette implémentation s'amuser à faire une implémentation par système.

Pour la STL de SGI, c'est encore plus compliqué, puisque le
développeur n'a a priori aucune idée du type de machine ou d'OS sur
lequel l'implémentation sera utilisée.

Publicité
Suivre les réponses
Poster une réponse
Anonyme