Je voudrais utiliser l'ERMSB (Enhanced REP MOVSB) pour obtenir une bande passante élevée pour un memcpy
personnalisé.
L'ERMSB a été introduit avec la microarchitecture Ivy Bridge. Consultez la section "Opération Enhanced REP MOVSB et STOSB (ERMSB)" dans le manuel d'optimisation d'Intel si vous ne savez pas ce qu'est l'ERMSB.
La seule manière que je connaisse de le faire directement est avec l'assemblage inline. J'ai obtenu la fonction suivante de https://groups.google.com/forum/#!topic/gnu.gcc.help/-Bmlm_EG_fE
static inline void *__movsb(void *d, const void *s, size_t n) {
asm volatile ("rep movsb"
: "=D" (d),
"=S" (s),
"=c" (n)
: "0" (d),
"1" (s),
"2" (n)
: "memory");
return d;
}
Cependant, lorsque j'utilise cela, la bande passante est bien inférieure à celle de memcpy
. __movsb
atteint 15 Go/s et memcpy
atteint 26 Go/s avec mon système i7-6700HQ (Skylake), Ubuntu 16.10, DDR4@2400 MHz dual channel 32 Go, GCC 6.2.
Pourquoi la bande passante est-elle beaucoup plus basse avec REP MOVSB
? Que puis-je faire pour l'améliorer?
Voici le code que j'ai utilisé pour tester cela.
//gcc -O3 -march=native -fopenmp foo.c
#include
#include
#include
#include
#include
#include
static inline void *__movsb(void *d, const void *s, size_t n) {
asm volatile ("rep movsb"
: "=D" (d),
"=S" (s),
"=c" (n)
: "0" (d),
"1" (s),
"2" (n)
: "memory");
return d;
}
int main(void) {
int n = 1<<30;
//char *a = malloc(n), *b = malloc(n);
char *a = _mm_malloc(n,4096), *b = _mm_malloc(n,4096);
memset(a,2,n), memset(b,1,n);
__movsb(b,a,n);
printf("%d\n", memcmp(b,a,n));
double dtime;
dtime = -omp_get_wtime();
for(int i=0; i<10; i++) __movsb(b,a,n);
dtime += omp_get_wtime();
printf("dtime %f, %.2f Go/s\n", dtime, 2.0*10*1E-9*n/dtime);
dtime = -omp_get_wtime();
for(int i=0; i<10; i++) memcpy(b,a,n);
dtime += omp_get_wtime();
printf("dtime %f, %.2f Go/s\n", dtime, 2.0*10*1E-9*n/dtime);
}
La raison pour laquelle je m'intéresse à rep movsb
est basée sur ces commentaires
Remarquez que sur Ivybridge et Haswell, avec des tampons trop grands pour tenir dans le LLC, vous pouvez battre movntdqa en utilisant rep movsb; movntdqa entraîne un RFO dans le LLC, tandis que rep movsb ne le fait pas... rep movsb est significativement plus rapide que movntdqa lors de la diffusion en mémoire sur Ivybridge et Haswell (mais sachez que pré-Ivybridge il est lent!)
Qu'est-ce qui manque/sub-optimal dans cette implémentation de memcpy?
Voici mes résultats sur le même système à partir de tinymembnech.
C copie en arrière : 7910.6 Mo/s (1.4%)
C copie en arrière (blocs de 32 octets) : 7696.6 Mo/s (0.9%)
C copie en arrière (blocs de 64 octets) : 7679.5 Mo/s (0.7%)
C copie : 8811.0 Mo/s (1.2%)
C copie prefetchée (pas de 32 octets) : 9328.4 Mo/s (0.5%)
C copie prefetchée (pas de 64 octets) : 9355.1 Mo/s (0.6%)
C copie en 2 passes : 6474.3 Mo/s (1.3%)
C copie en 2 passes prefetchée (pas de 32 octets) : 7072.9 Mo/s (1.2%)
C copie en 2 passes prefetchée (pas de 64 octets) : 7065.2 Mo/s (0.8%)
C remplissage : 14426.0 Mo/s (1.5%)
C remplissage (mélange dans des blocs de 16 octets) : 14198.0 Mo/s (1.1%)
C remplissage (mélange dans des blocs de 32 octets) : 14422.0 Mo/s (1.7%)
C remplissage (mélange dans des blocs de 64 octets) : 14178.3 Mo/s (1.0%)
---
memcpy standard : 12784.4 Mo/s (1.9%)
memset standard : 30630.3 Mo/s (1.1%)
---
copie MOVSB : 8712.0 Mo/s (2.0%)
copie MOVSD : 8712.7 Mo/s (1.9%)
copie SSE2 : 8952.2 Mo/s (0.7%)
copie SSE2 sans temporalité : 12538.2 Mo/s (0.8%)
copie SSE2 prefetchée (pas de 32 octets) : 9553.6 Mo/s (0.8%)
copie SSE2 prefetchée (pas de 64 octets) : 9458.5 Mo/s (0.5%)
copie SSE2 sans temporalité prefetchée (pas de 32 octets) : 13103.2 Mo/s (0.7%)
copie SSE2 sans temporalité prefetchée (pas de 64 octets) : 13179.1 Mo/s (0.9%)
copie SSE2 en 2 passes : 7250.6 Mo/s (0.7%)
copie SSE2 en 2 passes prefetchée (pas de 32 octets) : 7437.8 Mo/s (0.6%)
copie SSE2 en 2 passes prefetchée (pas de 64 octets) : 7498.2 Mo/s (0.9%)
copie SSE2 en 2 passes sans temporalité : 3776.6 Mo/s (1.4%)
remplissage SSE2 : 14701.3 Mo/s (1.6%)
remplissage SSE2 sans temporalité : 34188.3 Mo/s (0.8%)
Sur mon système, notez que copie SSE2 prefetchée
est aussi plus rapide que copie MOVSB
.
Dans mes tests initiaux, je n'ai pas désactivé le turbo. J'ai désactivé le turbo et testé à nouveau, mais cela ne semble pas faire beaucoup de différence. Cependant, changer la gestion de l'alimentation fait une grande différence.
Quand je fais
sudo cpufreq-set -r -g performance
Je vois parfois plus de 20 Go/s avec rep movsb
.
avec
sudo cpufreq-set -r -g powersave
le meilleur que je vois est d'environ 17 Go/s. Mais memcpy
ne semble pas être sensible à la gestion de l'alimentation.
J'ai vérifié la fréquence (en utilisant turbostat
) avec et sans SpeedStep activé, avec performance
et avec powersave
pour l'arrêt, une charge sur un core et une charge sur 4 cores. J'ai exécuté la multiplication de matrices denses de l'Intel MKL pour créer une charge et j'ai défini le nombre de threads en utilisant OMP_SET_NUM_THREADS
. Voici un tableau des résultats (nombres en GHz).
SpeedStep arrêt 1 core 4 cores
powersave DÉSACTIVÉ 0.8 2.6 2.6
performance DÉSACTIVÉ 2.6 2.6 2.6
powersave ACTIVÉ 0.8 3.5 3.1
performance ACTIVÉ 3.5 3.5 3.1
Cela montre qu'avec powersave
même avec SpeedStep désactivé, le CPU se met toujours en fréquence de repos de 0.8 GHz
. C'est seulement avec performance
sans SpeedStep que le CPU tourne à une fréquence constante.
J'ai utilisé par exemple sudo cpufreq-set -r performance
(car cpufreq-set
donnait des résultats étranges) pour changer les paramètres d'alimentation. Cela réactive le turbo donc j'ai dû le désactiver ensuite.
0 votes
"Que puis-je faire pour l'améliorer?" ... fondamentalement rien. L'implémentation
memcpy
dans la version actuelle du compilateur est très probablement aussi proche de la solution optimale que vous pouvez obtenir avec une fonction générique. Si vous avez un cas spécial comme déplacer toujours exactement 15 octets/ect, alors peut-être qu'une solution asm personnalisée pourrait battre le compilateur gcc, mais si votre source C est assez explicite sur ce qui se passe (donnant de bons indices au compilateur sur l'alignement, la longueur, etc), le compilateur produira très probablement un code machine optimal même pour ces cas spécialisés. Vous pouvez essayer d'améliorer d'abord la sortie du compilateur.7 votes
@KerrekSB Savez-vous ce qu'est le movsb rep amélioré ?
3 votes
@Ped7g, je n'attends pas que ce soit mieux que
memcpy
. Je m'attends à ce que ce soit aussi bon quememcpy
. J'ai utilisé gdb pour parcourirmemcpy
et j'ai vu qu'il entre dans une boucle principale avecrep movsb
. C'est donc apparemment ce quememcpy
utilise de toute façon (dans certains cas).2 votes
Changer l'ordre des tests. Quels résultats obtenez-vous ensuite?
2 votes
@Art, j'obtiens le même résultat (26 Go/s pour memcpy et 15 Go/s pour __movsb).
0 votes
D'accord. En cas de doute, suspectez le benchmark. Mais cela ne semble pas être le problème ici. Pour ce que ça vaut, c'est plus rapide sur une machine Ivy Bridge à laquelle j'avais accès (à la fois lors de la première et de la deuxième exécution).
0 votes
@Art, c'est intéressant! Je me demande pourquoi c'est sur votre système IVB. Oui, les tests de performance sont pénibles. J'ai récemment répondu à une question que j'ai dû éditer plusieurs fois en raison de problèmes de tests de performances auxquels je ne m'attendais pas.
0 votes
@Art peut-être que
enhanced rep movsb
n'est pas si amélioré sur Skylake (mon système) ? Je ne comprends toujours pas pourquoi tu as dû changer l'ordre.0 votes
@Zboson L'ordre ne importait pas pour moi non plus. Le commentaire "Changer l'ordre" était avant que je trouve une machine avec le bon CPU. Il est aussi 50% plus rapide, ce qui est assez significatif. D'autre part, sur une autre machine avec un CPU plus récent, les performances sont inversées.
0 votes
@Art, quelle fonction était 50% plus rapide et sur quelle machine ?
1 votes
@Zboson la fonction movsb était 50% plus rapide sur une machine Ivy Bridge.
0 votes
@Zboson : Non, je n'ai pas entendu parler de ça, désolé. Le terme est-il défini dans le manuel d'instruction Intel ?
3 votes
@KerrekSB, oui, c'est dans la section "3.7.6 Opération améliorée REP MOVSB et STOSB (ERMSB)"
0 votes
Intéressant. Avez-vous vérifié avec cpuid que la fonctionnalité est disponible sur votre CPU?
3 votes
Le manuel d'optimisation suggère que ERMSB est meilleur pour fournir une taille de code réduite et une meilleure efficacité que le traditionnel REP-MOV/STO, mais "implémenter memcpy en utilisant ERMSB pourrait ne pas atteindre le même niveau de débit que l'utilisation d'alternatives AVX de 256 bits ou 128 bits, selon la longueur et les facteurs d'alignement." La façon dont je comprends cela est qu'il est amélioré pour les situations où vous auriez précédemment utilisé des instructions rep, mais il ne vise pas à rivaliser avec les alternatives modernes à haut débit.
0 votes
@KerrekSB, non. Je suppose que les processeurs depuis Ivy Bridge l'ont.
less /proc/cpuinfo | grep erms
montre erms.0 votes
@Zboson: Oui, même chose, c'est assez bien.
0 votes
@KerrekSB, ouais, j'ai lu cette déclaration mais j'étais confus par cela. Je me base sur le commentaire "rep movsb est significativement plus rapide que movntdqa lors du streaming vers la mémoire sur Ivybridge et Haswell (mais sachez qu'avant Ivybridge c'est lent!)" (voir la mise à jour à la fin de ma question).
1 votes
Comment serait-il de parcourir le code machine dans un débogueur et de vérifier si votre memcpy utilise effectivement movntdqa? Il semble plausible qu'il utilise des instructions SSE ou AVX à la place. J'ai le sentiment que ERMSB est censé être meilleur que certains éléments, pas meilleur que tout.
0 votes
J'ai utilisé
gdb
pour étudiermemcpy
. Pour une taille définie à l'exécution, il utilisait des magasins non temporels et un préchargement. Pour la même taille (1 Go) définie à la compilation, il utilisaitrep movsb
. Je n'ai regardé qu'une fois donc il est possible que j'ai mal interprété quelque chose. Ma propre implémentation utilisantmovntdqa
se comporte à peu près aussi bien quememcpy
.1 votes
@Zboson: Vous avez besoin d'un meilleur micro-benchmark/test de timing. Votre source et votre destination sont tous les deux alignés sur des vecteurs AVX, ce qui affectera la manière dont le compilateur implémentera la fonction memcpy(). J'ai effectué des tests similaires en utilisant des tuples source-cible-longueur pseudo-aléatoires prégénérés, avec différentes situations d'alignement testées séparément, pour mieux imiter des cas d'utilisation réels. Mais, mon code du monde réel copie généralement des données froides, et le timing du comportement du cache froid est difficile. Peut-être envisager de chronométrer une tâche réelle lourde en memcpy()/memmove()?
0 votes
@NominalAnimal, c'est un point intéressant. Vous voulez dire que l'ERMSB est utile dans des situations moins idéales, par exemple lorsque la destination et la source ne sont pas alignées. Je pensais que l'alignement était essentiel pour l'ERMSB? Dans tous les cas, si vous pouvez démontrer où l'ERMSB est utile, ce serait une bonne réponse. Montrez-moi un meilleur microbenchmark/test de timing.
2 votes
@NominalAnimal Le Manuel d'Optimisation d'Intel, Tableau 3-4 affirme que lorsque à la fois la source et la destination sont alignées sur au moins 16 octets et que la taille du transfert est de 128 à 4096 octets, ERMSB répond ou dépasse le
memcpy()
basé sur AVX d'Intel. Bien que personne ne sache ce qu'est cememcpy()
, on peut raisonnablement supposer qu'Intel saurait comment obtenir plus de 50% de la bande passante maximale sur leur propre puce.0 votes
@IwillnotexistIdonotexist, vous n'avez pas besoin de comparer à
memcpy
. Vous pourriez comparer ERMSB à une solution SSE/AVX ou mieux à une solution avec des opérations de stockage non temporelles. C'est ce que je ferais dans ce cas: utiliser des opérations de stockage non temporelles. Mais ce commentaire et le commentaire qui a suivi ont dit que même dans le cas de 1 Go, ERMSB devrait l'emporter. Les opérations de stockage non temporelles ne devraient-elles pas empêcher les prélecteurs de lire la destination? Je pensais que c'était là l'intérêt de les utiliser.5 votes
@Zboson Mon
memcpy()
de glibc utilise les AVX NT stores. Et à la fois les NT stores et les ERMSB se comportent de manière write-combining, et par conséquent ne devraient pas nécessiter de RFO's. Néanmoins, mes tests de performance sur ma propre machine montrent que monmemcpy()
et mon ERMSB atteignent tous deux leur limite à 2/3 de la bande passante totale, comme votrememcpy()
(mais pas votre ERMSB) l'a fait. Par conséquent, il y a clairement une transaction de bus supplémentaire quelque part, et cela ressemble beaucoup à un RFO.0 votes
@JeNexisteraipasTaimeNexistepas votre observation 2/3 est très intéressante. Je pense que je peux faire mieux que 2/3 en utilisant deux fils. Je ne suis pas sûr pourquoi mon ERMSB sur Skylake se comporte moins bien que votre ERMSB sur Haswell.
0 votes
@IwillnotexistIdonotexist, avez-vous vu un quelconque bénéfice pour plus de 2 threads? Je n'ai jamais regardé les compteurs de performance auparavant. C'est une faiblesse que je dois corriger. Quels outils utilisez-vous pour cela? Agner Fog a un outil pour ça mais c'était un peu compliqué. Je devrais y jeter un oeil à nouveau. Et que pensez-vous de
perf
? Si vous répondez à la question, veuillez partager les détails.2 votes
@Zboson À 2 threads, c'est environ 21Go/s, à 4+ ça atteint la saturation à 23Go/s. J'examine les compteurs de performance en utilisant un logiciel fait maison que j'ai écrit:
libpfc
. C'est peu fiable, beaucoup plus limité queocperf.py
, uniquement connu pour fonctionner sur ma propre machine, ne fonctionne correctement que pour les codes monoprocesseurs, mais parce que je peux facilement (re)programmer les compteurs et accéder aux timings de l'intérieur du programme, et que je peux bien encadrer le code à vérifier, cela répond à mes besoins. Un jour, j'aurai le temps de résoudre ses nombreux problèmes.1 votes
En cas où quelqu'un se soucie voici une solution d'assemblage en ligne plus simple
void __movsb(void* dst, const void* src, size_t size) { __asm__ __volatile__("rep movsb" : "+D"(dst), "+S"(src), "+c"(size) : : "memory"); }
que j'ai trouvée ici hero.handmade.network/forums/code-discussion/t/…0 votes
Il semble qu'une réponse raisonnable pourrait être que c'était plus rapide, ou du moins aussi rapide en IVB (selon certains résultats référencés ici), mais que le micro-code associé ne reçoit pas nécessairement toute l'attention à chaque génération, de sorte qu'il devient plus lent que le code explicite, qui utilise toujours la fonctionnalité de base du CPU qui est garantie d'être accordée, de bien fonctionner avec le prefetching, etc. Par exemple, voir le commentaire d'Andy Glew ici:
2 votes
Le gros point faible de la réalisation rapide de chaînes de caractères en microcode était ... et (b) le microcode devenait de plus en plus désynchronisé à chaque génération, devenant de plus en plus lent jusqu'à ce que quelqu'un s'en charge pour le corriger. - Andy Glew
3 votes
Il est également intéressant de noter que les performances rapides des chaînes de caractères sont effectivement très pertinentes dans, par exemple, les méthodes du noyau Linux telles que
read()
etwrite()
qui copient des données dans l'espace utilisateur : le noyau ne peut pas (n'utilise pas) utiliser des registres ou un code SIMD, donc pour un memcpy rapide, il doit soit utiliser des charges/stores de 64 bits, soit, plus récemment, il utiliserarep movsb
ourep rmovd
s'ils sont détectés comme rapides sur l'architecture. Ils bénéficient donc grandement des déplacements importants sans avoir explicitement besoin d'utiliser les registresxmm
ouymm
.0 votes
Par curiosité, calculez-vous vos chiffres de bande passante deux fois la taille de la longueur de
memcpy
ou une fois? Autrement dit, votre chiffre est-il un chiffre de "bande passante mémoire" ou un chiffre de "bande passante memcpy"? Bien sûr, cela ne change pas les performances relatives entre les techniques, mais cela m'aide à comparer avec mon système.1 votes
@BeeOnRope J'utilise 2 fois la taille de la fonction
memcpy
, c'est-à-dire la bande passante mémoire. Comme vous avez le même processeur que moi, avez-vous testé mon code dans ma question à ce sujet? Si oui, avez-vous obtenu le même résultat? Vous devez compiler avec-mavx
en raison de ce bogue. Essayez les mêmes options de compilation exactes que j'ai utiliséesgcc -O3 -march=native -fopenmp foo.c
.0 votes
@Zboson - intéressant - alors vos chiffres semblent cohérents avec ma boîte pour le NT
memcpy
(environ 13 Go copiés, soit 26 Go/s de bande passante), mais pas pour lerep movsb
où je vois plus de 20 Go/s de bande passante, mais vous signalez seulement 15. Je vais essayer votre code. Au fait, je suppose que vous avez désactivé le turbo pour vos tests (c'est pourquoi vous signalez 2,6 GHz ?). Je l'ai fait, bien que j'aurais dû le mentionner explicitement dans ma réponse.0 votes
@Zboson - J'obtiens environ 19,5 Go/s et 23,5 Go/s pour
rep movsb
etmemcpy
respectivement avec votre code. Très curieusement, cela ne correspond pas à vos résultats, puisque nous avons le même processeur. Il y a toutes sortes de choses intéressantes comme un "turbo mémoire efficace" qui peuvent jouer un rôle important ici - laissez-moi jouer un peu. C'est avec le turbo désactivé. Avec le turbo activé, j'obtiens environ 20 contre 25. Le turbo semble aider la versionmemcpy
plus que la versionrep movs
.1 votes
Je obtiens des résultats plus proches des vôtres si je passe au gouverneur
powersave
: environ 17,5 Go/s contre 23,5 Go/s. C'est-à-dire que les performances derep movsb
chutent mais pas celles dememcpy
. En effet, des mesures répétées montrent qu'avec le gouverneurpowersave
, mon processeur ne fonctionne qu'à environ 2,3 GHz pour le benchmarkmovs
, mais à 2,6 GHz pour le benchmarkmemcpy
. Une partie significative de la différence dans votre cas est probablement expliquée par la gestion de l'alimentation. Fondamentalement, le turbo écoénergétique (désormais PET) utilise une heuristique pour déterminer si le code est "bloqué mémoire" et abaisse la fréquence du processeur car une haute fréquence est "inutile".1 votes
Alors,
rep movs
subit un traitement défavorable (en termes de performances, peut-être économise-t-il de l'énergie cependant!) de l’heuristique PET, peut-être parce que l'heuristique voit qu'il y a un long arrêt sur une instruction, tandis que la version AVX hautement déroulée exécute encore beaucoup d'instructions. J'ai déjà vu cela lors de tests d'un algorithme sur une plage de valeurs de paramètres : à une certaine valeur, il y a une chute de performances beaucoup plus importante que prévue : mais ce qui se passe, c'est que soudainement, le seuil PET était atteint et le processeur a diminué sa fréquence (ce qui nuit toujours aux performances).0 votes
@BeeOnRope Je n'ai pas désactivé Turbo dans mes tests. Pourquoi cela importait-il pour les opérations liées à la bande passante mémoire? Quoi qu'il en soit, je viens de le désactiver (j'ai vérifié qu'il était bien désactivé en exécutant un outil de mesure de fréquence personnalisé) et cela ne semble pas faire beaucoup de différence. Mais changer la gestion de l'alimentation fait une différence. Avec
performance
rep movsb
atteint jusqu'à 20 Go/s, mais avecpowersave
il atteint au maximum 17 Go/s. J'ai ajouté ces informations à la fin de ma question.0 votes
@BeeOnRope comment les paramètres d'économie d'énergie (PET) influent-ils lorsque le turbo est désactivé ? Je suis allé dans le BIOS et j'ai désactivé SpeedStep. Ne devrait-il pas exécuter le CPU à une fréquence fixe ? Pourquoi
powersave
ouperformance
importeraient-ils dans ce cas si le CPU fonctionne à une fréquence constante ?0 votes
Eh bien, PET est probablement un abus de langage car apparemment cela n'affecte pas seulement les fréquences supérieures à nominales, mais plutôt l'ensemble de la plage DVFS. Cela a du sens - ce n'est pas comme si la fréquence nominale était particulièrement spéciale : s'il est logique de la réduire à 2,6 GHz, il peut également être logique de la réduire à 2,3 ou 1,0 ou autre. Désactiver SpeedStep va probablement fonctionner, mais c'est facile à vérifier, il suffit d'exécuter
grep /proc/cpu MHz
quelques fois et d'observer les valeurs, ou de lancerturbostat
. J'ai exécuté le benchmark commeperf ./a.out
pour faire mon observation : cela vous donne l'effet en GHz pour le processus.0 votes
Si votre CPU est verrouillé,
powersave
etperformance
peut-être ne devraient pas importer (il reste la question des fréquences de l'uncore, qui sont indépendantes, mais aucun outil standard ne les rapporte, autant que je sache). De plus, il peut y avoir d'autres aspects d'économie d'énergie non directement liés à la fréquence qui sont contrôlés par ce paramètre (par exemple, l'agressivité du passage à des C-states plus élevés ?).0 votes
À propos du turbo, cela peut faire une différence significative pour les choses liées à la mémoire, car cela affecte les performances uncore et donc impacte la latence, puisque une grande partie de la latence d'un accès mémoire est un travail uncore, qui est accéléré par le turbo (mais c'est aussi complexe en raison de l'interaction entre les heuristiques d'économie d'énergie, et le fait que les fréquences uncore et core sont en partie indépendantes). Étant donné que nos puces semblent atteindre la limite réelle de la bande passante de la DRAM (c'est-à-dire pas une limite de concurrence-occupation comme indiqué dans la discussion sur les "plateformes limitées par la latence" ci-dessous), cela peut ne pas s'appliquer et je ne vois pas beaucoup d'effet sur mon CPU. @Zboson
0 votes
@Art pensez-vous que vous pourriez exécuter tinybenchmark (voir la réponse de BeeOnRope) sur votre système Ivy Bridge et ajouter les résultats à la fin de ma question ?
0 votes
@BeeOnRope. J'ai vérifié la fréquence. Avec
powersave
, le CPU reste inactif à 0,8 GHz même avec SpeedStep désactivé. Ce n'est qu'avecperformance
que le CPU est verrouillé à 2,6 GHz avec SpeedStep désactivé. Voir la mise à jour à la fin de ma question.0 votes
@Zboson - exactement, je me souviens de quelque chose de similaire : le pilote
intel_pstate
utilisera toujours les P-states pour contrôler la fréquence même si SS est désactivé dans le BIOS. Vous pouvez également utiliserintel_pstate=disabled
comme paramètre de démarrage pour le désactiver complètement, vous permettant ainsi d'utiliser la gestion de l'alimentation par défaut, y compris le gouverneur "utilisateur" qui définit la fréquence à ce que vous voulez (pas de fréquences turbo cependant). Anecdote intéressante : sansintel_pstate
, mon processeur ne fonctionnerait jamais au-dessus de 3,4 GHz (c'est-à-dire que les derniers 100 MHz du mode turbo étaient inaccessibles). Avecintel_pstate
, aucun problème.1 votes
Soit dit en passant, il y a un vrai terrier de lapin intéressant à descendre avec ces économies d'énergie : par exemple, exécuter deux benchmarks côte à côte peut donner lieu à plus de 2x de débit total (c'est-à-dire un "scalabilité superlinéaire" avec plus de threads, ce qui est vraiment bizarre) parce qu'un benchmark maintient une fréquence de cœur ou de non-cœur élevée ce qui aide l'autre, mais peut-être mérite-t-il une question entièrement distincte. Je pense que l'économie d'énergie est une partie de la performance
rep movsb
quelque peu plus pauvre, mais ce n'est pas toute l'histoire (même à MHz égal, c'est plus lent).1 votes
Soit dit en passant, j'ai mesuré la consommation d'énergie de
rep movsb
(en mode économie d'énergie à la fréquence la plus basse) par rapport àmemcpy
, mais la puissance (c'est-à-dire les watts) était seulement légèrement inférieure, et l'énergie totale consommée était plus élevée (car elle fonctionne plus longtemps). Il n'y a donc aucun avantage en termes d'économie d'énergie...2 votes
@BeeOnRope De toute évidence, il devrait y avoir une salle de discussion RFB-x86 (Demande de Bancs d'Essai - x86) dans le seul but de rétro-ingénierie des facteurs influençant les performances des processeurs x86.
1 votes
@Zboson - J'utilise des commandes comme
sudo cpupower -c 0,1,2,3 frequency-set -g performance
- selon ce que je comprends,cpuopwer
est la commande la plus à jour et maintenue pour la gestion de l'alimentation (elle peut également ajuster le "perf bias" sur les puces Intel récentes). En utilisant cette commande, passer en modeperformance
ne semble pas affecter le turbo. J'utilise ce script pour activer/désactiver le turbo, bien qu'il semble peut-être plus simple d'utiliser/sys/devices/system/cpu/intel_pstate/no_turbo
si vous utilisezintel_pstate
.0 votes
@BeeOnRope re : 'Essentiellement, le turbo efficace en énergie (ci-après PET) utilise une méthode heuristic pour déterminer si le code est "limité par l'arrêt de la mémoire" et réduit la vitesse du CPU car une fréquence élevée est "inutile"'. Des lectures complémentaires à ce sujet ? Je ne trouve aucun des mots-clés dans le Manuel d'optimisation.
0 votes
@Noah - c'était quelque chose que j'ai découvert ici sur SO en répondant à une question sur la raison pour laquelle
rep movsb
était plus lent que les instructions d'écriture de copie explicites : cet effet expliquait une partie de l'écart. Je ne suis pas au courant de toute discussion à ce sujet en dehors de SO : vous pourriez chercher cette question et la lier si vous la trouvez. Je n'ai pas pu la trouver mais je n'y ai pas passé beaucoup de temps et la recherche SO renvoie étrangement peu de résultats.