Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Marc Boyer
Le 06-02-2012, Lucas Levrel a écrit :
Je dois initialiser à zéro un tableau de doubles, dans un programme compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle for, ou ex-æquo ?
Disons que ta question n'a pas beaucoup de sens.
Déjà, j'imagine que tu vas faire un memset en mettant tous les bits à 0, en faisant l'hypothèse qu'un float dont tous les bits sont nuls vaut 0.0. C'est sûrement le cas sur ton Xeon, mais je ne pense pas que ce soit garanti par la norme. L'avantage de la boucle for est d'ếtre portable.
Côté lisibilité, je miserais aussi sur la boucle for.
Côté perf pures, j'ai du mal à imaginer un contexte où la mise à 0 d'un tableau de flottant soit une partie critique en temps de calcul. Ca faut quand même phase d'initialisation, pas le coeur du souci.
Tout ceci étant dit, ça peut dépendre de pleins de choses.
Supposons que le compilo n'ait pas de traitement spécifique pour la fonction memset: on compare la qualité de l'implantation de memset à la qualité de l'optimiseur d'icc. Donc, faudrait préciser quel memset, de quelle libc. Quand memset reçoit ton tableau, il ne sait pas s'il est bien aligné ou pas, et il doit calculer s'il a le droit de faire des grandes écritures de 64 bits, ou pleins de petites de 8 bits. Alors que le compilo le sait lui. Si memset est une fonction "comme une autre", il y a un appel de fonction, peut-être un défaut de cache.
Mais il est aussi possible que le compilo fasse de l'appel à memset un cas particulier (il "reconnait" cette fonction).
Tout ça pour dire que le plus simple, une fois que tu t'es assuré que tu avais vraiment besoin de savoir ça, que la performance primait sur la lisibilité, il te reste à faire les tests, sur différentes tailles de tableau (les résultats pourraient varier), éventuellement à regarder l'assembleur généré.
Marc Boyer -- À mesure que les inégalités regressent, les attentes se renforcent. François Dubet
Le 06-02-2012, Lucas Levrel <lucas.levrel@u-pec.fr> a écrit :
Je dois initialiser à zéro un tableau de doubles, dans un programme
compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle for,
ou ex-æquo ?
Disons que ta question n'a pas beaucoup de sens.
Déjà, j'imagine que tu vas faire un memset en mettant tous les
bits à 0, en faisant l'hypothèse qu'un float dont tous les bits
sont nuls vaut 0.0.
C'est sûrement le cas sur ton Xeon, mais je ne pense pas
que ce soit garanti par la norme. L'avantage de la boucle
for est d'ếtre portable.
Côté lisibilité, je miserais aussi sur la boucle for.
Côté perf pures, j'ai du mal à imaginer un contexte
où la mise à 0 d'un tableau de flottant soit une partie
critique en temps de calcul. Ca faut quand même phase
d'initialisation, pas le coeur du souci.
Tout ceci étant dit, ça peut dépendre de pleins de choses.
Supposons que le compilo n'ait pas de traitement spécifique
pour la fonction memset: on compare la qualité de l'implantation
de memset à la qualité de l'optimiseur d'icc. Donc, faudrait
préciser quel memset, de quelle libc.
Quand memset reçoit ton tableau, il ne sait pas s'il est
bien aligné ou pas, et il doit calculer s'il a le droit de faire
des grandes écritures de 64 bits, ou pleins de petites de 8 bits.
Alors que le compilo le sait lui.
Si memset est une fonction "comme une autre", il y a un appel
de fonction, peut-être un défaut de cache.
Mais il est aussi possible que le compilo fasse de l'appel à
memset un cas particulier (il "reconnait" cette fonction).
Tout ça pour dire que le plus simple, une fois que tu t'es
assuré que tu avais vraiment besoin de savoir ça, que la
performance primait sur la lisibilité, il te reste à faire les
tests, sur différentes tailles de tableau (les résultats
pourraient varier), éventuellement à regarder l'assembleur
généré.
Marc Boyer
--
À mesure que les inégalités regressent, les attentes se renforcent.
François Dubet
Je dois initialiser à zéro un tableau de doubles, dans un programme compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle for, ou ex-æquo ?
Disons que ta question n'a pas beaucoup de sens.
Déjà, j'imagine que tu vas faire un memset en mettant tous les bits à 0, en faisant l'hypothèse qu'un float dont tous les bits sont nuls vaut 0.0. C'est sûrement le cas sur ton Xeon, mais je ne pense pas que ce soit garanti par la norme. L'avantage de la boucle for est d'ếtre portable.
Côté lisibilité, je miserais aussi sur la boucle for.
Côté perf pures, j'ai du mal à imaginer un contexte où la mise à 0 d'un tableau de flottant soit une partie critique en temps de calcul. Ca faut quand même phase d'initialisation, pas le coeur du souci.
Tout ceci étant dit, ça peut dépendre de pleins de choses.
Supposons que le compilo n'ait pas de traitement spécifique pour la fonction memset: on compare la qualité de l'implantation de memset à la qualité de l'optimiseur d'icc. Donc, faudrait préciser quel memset, de quelle libc. Quand memset reçoit ton tableau, il ne sait pas s'il est bien aligné ou pas, et il doit calculer s'il a le droit de faire des grandes écritures de 64 bits, ou pleins de petites de 8 bits. Alors que le compilo le sait lui. Si memset est une fonction "comme une autre", il y a un appel de fonction, peut-être un défaut de cache.
Mais il est aussi possible que le compilo fasse de l'appel à memset un cas particulier (il "reconnait" cette fonction).
Tout ça pour dire que le plus simple, une fois que tu t'es assuré que tu avais vraiment besoin de savoir ça, que la performance primait sur la lisibilité, il te reste à faire les tests, sur différentes tailles de tableau (les résultats pourraient varier), éventuellement à regarder l'assembleur généré.
Marc Boyer -- À mesure que les inégalités regressent, les attentes se renforcent. François Dubet
Antoine Leca
Lucas Levrel écrivit :
Je dois initialiser à zéro un tableau de doubles, dans un programme compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle for, ou ex-æquo ?
Réponse générique pour toute question de micro-optimisation : tu testes les deux options, et tu choisis la meilleure. Et *surtout*, tu notes dans un coin de refaire ce test régulièrement (car l'environnement général, par exemple les algorithmes choisis, peut avoir une influence)
Maintenant, dans ce cas en particulier, si memset() donne un plus mauvais résultat qu'une boucle for, je commencerais par me préoccuper sérieusement de la qualité en matière d'optimisation de la bibliothèque standard que tu utilises.
Antoine
Lucas Levrel écrivit :
Je dois initialiser à zéro un tableau de doubles, dans un programme
compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle
for, ou ex-æquo ?
Réponse générique pour toute question de micro-optimisation : tu testes
les deux options, et tu choisis la meilleure. Et *surtout*, tu notes
dans un coin de refaire ce test régulièrement (car l'environnement
général, par exemple les algorithmes choisis, peut avoir une influence)
Maintenant, dans ce cas en particulier, si memset() donne un plus
mauvais résultat qu'une boucle for, je commencerais par me préoccuper
sérieusement de la qualité en matière d'optimisation de la bibliothèque
standard que tu utilises.
Je dois initialiser à zéro un tableau de doubles, dans un programme compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle for, ou ex-æquo ?
Réponse générique pour toute question de micro-optimisation : tu testes les deux options, et tu choisis la meilleure. Et *surtout*, tu notes dans un coin de refaire ce test régulièrement (car l'environnement général, par exemple les algorithmes choisis, peut avoir une influence)
Maintenant, dans ce cas en particulier, si memset() donne un plus mauvais résultat qu'une boucle for, je commencerais par me préoccuper sérieusement de la qualité en matière d'optimisation de la bibliothèque standard que tu utilises.
Antoine
espie
In article , Lucas Levrel wrote:
Bonjour,
Je dois initialiser à zéro un tableau de doubles, dans un programme compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle for, ou ex-æquo ?
Si c'est vaguement correctement foutu, c'est la bande passante d'acces a la memoire qui va dominer, de tres tres loin. Dans les deux cas, tu mets plein d'octets "a zero" (confere les remarques des autres sur la portabilite de l'operation!) et c'est l'acces memoire qui va prendre le plus de temps, loin devant les instructions processeur...
En fait, si tu veux gagner du temps, il faut compter les vrais temps d'acces a la memoire et au cache: on n'a pas la moindre idee de ce que tu nous ponds comme algo, mais ca peut etre interessant de mettre ton tableau "a 0" juste avant d'en faire quelque chose, histoire que les donnees concernees soient encore dans le cache.
In article <alpine.LNX.2.00.1202061413120.4141@coulomb.u-pec.fr>,
Lucas Levrel <lucas.levrel@u-pec.fr> wrote:
Bonjour,
Je dois initialiser à zéro un tableau de doubles, dans un programme
compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle for,
ou ex-æquo ?
Si c'est vaguement correctement foutu, c'est la bande passante d'acces
a la memoire qui va dominer, de tres tres loin. Dans les deux cas,
tu mets plein d'octets "a zero" (confere les remarques des autres sur
la portabilite de l'operation!) et c'est l'acces memoire qui va prendre
le plus de temps, loin devant les instructions processeur...
En fait, si tu veux gagner du temps, il faut compter les vrais temps d'acces
a la memoire et au cache: on n'a pas la moindre idee de ce que tu nous
ponds comme algo, mais ca peut etre interessant de mettre ton tableau "a 0"
juste avant d'en faire quelque chose, histoire que les donnees concernees
soient encore dans le cache.
Je dois initialiser à zéro un tableau de doubles, dans un programme compilé avec le compilateur Intel en -O3 et exécuté sur un Xeon.
Qu'est-ce qui sera le plus rapide à l'exécution : memset, une boucle for, ou ex-æquo ?
Si c'est vaguement correctement foutu, c'est la bande passante d'acces a la memoire qui va dominer, de tres tres loin. Dans les deux cas, tu mets plein d'octets "a zero" (confere les remarques des autres sur la portabilite de l'operation!) et c'est l'acces memoire qui va prendre le plus de temps, loin devant les instructions processeur...
En fait, si tu veux gagner du temps, il faut compter les vrais temps d'acces a la memoire et au cache: on n'a pas la moindre idee de ce que tu nous ponds comme algo, mais ca peut etre interessant de mettre ton tableau "a 0" juste avant d'en faire quelque chose, histoire que les donnees concernees soient encore dans le cache.
Xavier Roche
Le 06/02/2012 17:54, Antoine Leca a écrit :
Maintenant, dans ce cas en particulier, si memset() donne un plus mauvais résultat qu'une boucle for, je commencerais par me préoccuper sérieusement de la qualité en matière d'optimisation de la bibliothèque standard que tu utilises.
Ça dépend: remplir un petit tableau avec une petite boucle sans effectuer de branchement dans la bibliothèque standard (et donc rester sur la même ligne de cache de code), pour au final déplacer le même nombre d'octets de la mémoire vers le cache, le gagnant n'est pas évident (j'imagine que le facteur limitant sera mémoire <=> cache ici).
Après, on peut espérer que memset() soit un "builtin" dans pas mal de cas.
Mais bon, micro-optimisation, en effet, et totalement anecdotique amha.
(pour la portabilité, le memset() est probablement zen, dans la mesure où 0.0 == tous les bits a zéro en IEEE 754 -- mais il faut travailler dans un environnement qui suit IEEE 754 évidemment :p)
Le 06/02/2012 17:54, Antoine Leca a écrit :
Maintenant, dans ce cas en particulier, si memset() donne un plus
mauvais résultat qu'une boucle for, je commencerais par me préoccuper
sérieusement de la qualité en matière d'optimisation de la bibliothèque
standard que tu utilises.
Ça dépend: remplir un petit tableau avec une petite boucle sans
effectuer de branchement dans la bibliothèque standard (et donc rester
sur la même ligne de cache de code), pour au final déplacer le même
nombre d'octets de la mémoire vers le cache, le gagnant n'est pas
évident (j'imagine que le facteur limitant sera mémoire <=> cache ici).
Après, on peut espérer que memset() soit un "builtin" dans pas mal de cas.
Mais bon, micro-optimisation, en effet, et totalement anecdotique amha.
(pour la portabilité, le memset() est probablement zen, dans la mesure
où 0.0 == tous les bits a zéro en IEEE 754 -- mais il faut travailler
dans un environnement qui suit IEEE 754 évidemment :p)
Maintenant, dans ce cas en particulier, si memset() donne un plus mauvais résultat qu'une boucle for, je commencerais par me préoccuper sérieusement de la qualité en matière d'optimisation de la bibliothèque standard que tu utilises.
Ça dépend: remplir un petit tableau avec une petite boucle sans effectuer de branchement dans la bibliothèque standard (et donc rester sur la même ligne de cache de code), pour au final déplacer le même nombre d'octets de la mémoire vers le cache, le gagnant n'est pas évident (j'imagine que le facteur limitant sera mémoire <=> cache ici).
Après, on peut espérer que memset() soit un "builtin" dans pas mal de cas.
Mais bon, micro-optimisation, en effet, et totalement anecdotique amha.
(pour la portabilité, le memset() est probablement zen, dans la mesure où 0.0 == tous les bits a zéro en IEEE 754 -- mais il faut travailler dans un environnement qui suit IEEE 754 évidemment :p)
Erwan David
Xavier Roche écrivait :
Le 06/02/2012 17:54, Antoine Leca a écrit :
Maintenant, dans ce cas en particulier, si memset() donne un plus mauvais résultat qu'une boucle for, je commencerais par me préoccuper sérieusement de la qualité en matière d'optimisation de la bibliothèque standard que tu utilises.
Ça dépend: remplir un petit tableau avec une petite boucle sans effectuer de branchement dans la bibliothèque standard (et donc rester sur la même ligne de cache de code), pour au final déplacer le même nombre d'octets de la mémoire vers le cache, le gagnant n'est pas évident (j'imagine que le facteur limitant sera mémoire <=> cache ici).
Après, on peut espérer que memset() soit un "builtin" dans pas mal de cas.
Mais bon, micro-optimisation, en effet, et totalement anecdotique amha.
(pour la portabilité, le memset() est probablement zen, dans la mesure où 0.0 == tous les bits a zéro en IEEE 754 -- mais il faut travailler dans un environnement qui suit IEEE 754 évidemment :p)
S'il s'agit de mettre tous les bits à 0, initialiser en faisant double tab[size]={0.0} marchera aussi. Et c'est le compilateur qui choisira la manière de le faire
*attention* ne fonctionne que si 0.0 est représenté avec tous les bits à 0, mais comme on parle de le faire avec memset, on reste avec les même contraintes sur la plateforme.
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Maintenant, dans ce cas en particulier, si memset() donne un plus
mauvais résultat qu'une boucle for, je commencerais par me préoccuper
sérieusement de la qualité en matière d'optimisation de la bibliothèque
standard que tu utilises.
Ça dépend: remplir un petit tableau avec une petite boucle sans
effectuer de branchement dans la bibliothèque standard (et donc rester
sur la même ligne de cache de code), pour au final déplacer le même
nombre d'octets de la mémoire vers le cache, le gagnant n'est pas
évident (j'imagine que le facteur limitant sera mémoire <=> cache ici).
Après, on peut espérer que memset() soit un "builtin" dans pas mal de cas.
Mais bon, micro-optimisation, en effet, et totalement anecdotique amha.
(pour la portabilité, le memset() est probablement zen, dans la mesure
où 0.0 == tous les bits a zéro en IEEE 754 -- mais il faut travailler
dans un environnement qui suit IEEE 754 évidemment :p)
S'il s'agit de mettre tous les bits à 0, initialiser en faisant
double tab[size]={0.0} marchera aussi.
Et c'est le compilateur qui choisira la manière de le faire
*attention* ne fonctionne que si 0.0 est représenté avec tous les bits à
0, mais comme on parle de le faire avec memset, on reste avec les même
contraintes sur la plateforme.
--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Maintenant, dans ce cas en particulier, si memset() donne un plus mauvais résultat qu'une boucle for, je commencerais par me préoccuper sérieusement de la qualité en matière d'optimisation de la bibliothèque standard que tu utilises.
Ça dépend: remplir un petit tableau avec une petite boucle sans effectuer de branchement dans la bibliothèque standard (et donc rester sur la même ligne de cache de code), pour au final déplacer le même nombre d'octets de la mémoire vers le cache, le gagnant n'est pas évident (j'imagine que le facteur limitant sera mémoire <=> cache ici).
Après, on peut espérer que memset() soit un "builtin" dans pas mal de cas.
Mais bon, micro-optimisation, en effet, et totalement anecdotique amha.
(pour la portabilité, le memset() est probablement zen, dans la mesure où 0.0 == tous les bits a zéro en IEEE 754 -- mais il faut travailler dans un environnement qui suit IEEE 754 évidemment :p)
S'il s'agit de mettre tous les bits à 0, initialiser en faisant double tab[size]={0.0} marchera aussi. Et c'est le compilateur qui choisira la manière de le faire
*attention* ne fonctionne que si 0.0 est représenté avec tous les bits à 0, mais comme on parle de le faire avec memset, on reste avec les même contraintes sur la plateforme.
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Lucas Levrel
Merci pour toutes les remarques fort instructives, je n'en attendais pas moins des contributeurs du groupe !
Le coût de l'initialisation en question sera en effet mineur. C'est une remarque dans un bouquin, qui indiquait que memset serait plus rapide, qui a éveillé ma curiosité.
-- LL
Merci pour toutes les remarques fort instructives, je n'en attendais pas
moins des contributeurs du groupe !
Le coût de l'initialisation en question sera en effet mineur. C'est une
remarque dans un bouquin, qui indiquait que memset serait plus rapide, qui
a éveillé ma curiosité.
Merci pour toutes les remarques fort instructives, je n'en attendais pas moins des contributeurs du groupe !
Le coût de l'initialisation en question sera en effet mineur. C'est une remarque dans un bouquin, qui indiquait que memset serait plus rapide, qui a éveillé ma curiosité.