Question

Je suis intéressé à forcer un cache du processeur affleurant dans Windows (pour des raisons d'analyse comparative, je veux imiter à partir sans données dans le cache du processeur), de préférence une implémentation C de base ou appel Win32.

Y at-il une manière connue de le faire avec un appel système ou même quelque chose d'aussi sournoise que faire dire un grand memcpy?

plate-forme Intel i686 (P4 et up est bien aussi).

Était-ce utile?

La solution

Heureusement, il y a plus d'une façon de vider explicitement les caches.

L'instruction « wbinvd », écrit le contenu du cache modifié en arrière et marque les caches vides. Il exécute un cycle de bus pour faire des caches externes rincer leurs données. Malheureusement, il est une instruction privilégiée. Mais s'il est possible d'exécuter le programme d'essai dans quelque chose comme DOS, ceci est le chemin à parcourir. Cela a l'avantage de garder l'empreinte du cache du « OS » très faible.

En outre, il y a l'instruction "INVD" qui invalident caches sans les chasse d'eau de retour à la mémoire principale. Cela porte atteinte à la cohérence de la mémoire principale et le cache, donc vous devez prendre soin de par vous-même. Pas vraiment recommandé.

Pour des fins de comparaison, la solution la plus simple consiste à copier probablement un grand bloc de mémoire dans une région marquée avec WC (combinaison d'écriture) au lieu de WB. La région cartographiée de mémoire de la carte graphique est un bon candidat, ou vous pouvez marquer une région WC par vous-même via les registres MTRR.

Vous pouvez trouver des ressources sur l'analyse comparative des routines courtes à programmes d'essai pour la mesure de cycles d'horloge et le suivi des performances.

Autres conseils

Il y a des instructions d'assemblage x86 pour forcer l'unité centrale de traitement pour débusquer certaines lignes de cache (comme CLFLUSH ), mais ils sont assez obscurs. CLFLUSH en particulier les bouffées seulement une adresse choisie parmi les caches L1.

  

quelque chose d'aussi sournoise que faire dire un grand memcopy?

Oui, c'est l'approche la plus simple, et fera en sorte que les bouffées de CPU tous les niveaux de cache. Il suffit d'exclure le temps de vidage de la mémoire de votre benchmakrs et vous devriez avoir une bonne idée comment votre programme effectue sous la pression du cache.

Il n'y a malheureusement aucun moyen de vider explicitement le cache. Quelques-unes de vos options sont:

1.) Thrash le cache en faisant quelques opérations de mémoire très grandes entre les itérations du code vous évaluez la performance.

2). Activer Désactiver cache dans le x86 des registres de contrôle et de référence qui . Cela désactive probablement le cache d'instructions aussi, ce qui peut ne pas être ce que vous voulez.

3.) Mettre en oeuvre la partie de votre code de votre analyse comparative (si possible) en utilisant instructions non-temporelles . Bien que, ce ne sont que conseils au processeur sur l'utilisation du cache, il est toujours libre de faire ce qu'il veut.

1 est probablement le plus facile et suffisant pour vos besoins.

Modifier : Oops, je me suis trompé il y a une instruction pour invalider le cache x86, voir la réponse de drhirsch

instruction x86 WBINVD écrit en arrière et annule tous les caches. Il est décrit comme :

  

écrit avant toutes les lignes de mémoire cache modifié dans la mémoire cache interne du processeur à la mémoire principale et invalide (bouffées), les caches internes. L'instruction délivre alors un cycle de bus fonction spéciale qui dirige les caches externes d'écrire également données modifiées et un autre cycle de bus pour indiquer que devraient être invalidés les caches externes.

Fait important, l'instruction ne peut être exécutée dans ring0, à savoir le système d'exploitation. Ainsi, vos programmes userland ne peuvent pas utiliser simplement. Sous Linux, vous pouvez écrire un module de noyau qui peut exécuter cette instruction à la demande. En fait, quelqu'un a déjà écrit un tel module de noyau: https://github.com/batmac/wbinvd

Par chance, est vraiment petit code du module du noyau, de sorte que vous pouvez réellement vérifier avant le code de chargement des étrangers sur Internet dans votre noyau. Vous pouvez utiliser ce module (et déclencher l'exécution de l'instruction WBINVD) en lisant /proc/wbinvd, par exemple via cat /proc/wbinvd.

Cependant, je trouve que cette instruction (ou du moins ce module du noyau) est très lent. Sur mon i7-6700HQ je l'ai mesuré prendre 750μs! Ce chiffre semble très élevé pour moi, donc je pourrais avoir fait une erreur de mesure cela - s'il vous plaît garder cela à l'esprit! Explication de cette instruction juste dire:

  

La quantité de temps ou cycles pour WBINVD pour terminer varient en fonction de la taille et d'autres facteurs de différentes hiérarchies de cache.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top