1
votes

Pouvez-vous accéder directement au cache à l'aide de l'assembly?

La mise en cache est un élément essentiel en matière d'efficacité.

Je sais que la mise en cache se produit généralement automatiquement.

Cependant, j'aimerais contrôler moi-même l'utilisation du cache, car je pense que je peux faire mieux que certaines heuristiques qui ne connaissent pas le programme exact.

Par conséquent, j'aurais besoin d'instructions d'assemblage pour me déplacer directement vers ou depuis les cellules de la mémoire cache.

comme:

"START"
"move 1 to x"
"move 2 to y"
"move 3 to z"
"move 4 to a"
"move z to x"
"move y to x"
"END"

"START"
"move 1 to x"
"move 2 to y"
"move 3 to z"
"move 4 to a"
"move a to x"
"move y to x"
"END"

Je sais qu'il existe des instructions qui donnent des indications sur le "système de mise en cache", mais je ne sais pas si cela suffit car les astuces peuvent être ignorées ou elles ne sont peut-être pas suffisantes pour exprimer quelque chose d'exprimable par un tel déplacement vers / depuis l'ordre du cache.

Y a-t-il des assembleurs qui permettent un contrôle complet du cache?

Note latérale: pourquoi je voudrais améliorer la mise en cache:

considérons un processeur hypothétique avec 1 registre et un cache contenant 2 cellules.

considérons les deux programmes suivants:

(où x, y, z, a sont des cellules de mémoire)

movL1 address content

Dans le premier cas, vous utiliseriez le registre et le cache pour x , y, z (a n'est écrit qu'une seule fois) Dans le second cas, vous utiliseriez le registre et le cache pour a, x, y (z n'est écrit qu'une seule fois)

Si le CPU fait la mise en cache, il ne peut tout simplement pas décider avant temps auquel des deux cas ci-dessus il est confronté.

Il doit décider pour chacune des cellules de mémoire x, y, z si son contenu doit être mis en cache avant de savoir si le programme exécuté est non. 1 ou non. 2, parce que les deux programmes démarrent de la même façon.

Le programmeur, quant à lui, sait à l'avance quelles cellules de mémoire sont réutilisées et quand elles sont réutilisées.


8 commentaires

Ce n'est pas une question d'assembleur. C'est une question d'architecture que vous avez oublié de préciser. La réponse courte est non.


Ce n'est pas vraiment une question d'assembleurs qui le supportent, mais de contrôle de processeur de bas niveau. Je sais que sur certains (beaucoup?), Le BIOS initial / autre code utilisera le cache comme RAM avant que le DDR n'ait été initialisé. Bien que vous ayez probablement du mal à comprendre comment faire cela, les détails du processeur de bas niveau sont généralement cachés derrière les NDA. Ce n'est pas pertinent pour votre question, mais intéressant.


Sur la plupart des ISA, non. La seule façon d'utiliser le cache est en tant que cache transparent que vous chargez / stockez. Xeon Phi peut configurer son HBM en tant que cache ou "mémoire locale" séparée. Les processeurs x86 peuvent fonctionner en mode cache-as-RAM sans remplissage, utilisé par le BIOS au début du démarrage avant de configurer les contrôleurs DRAM. Mais ce n'est vraiment pas de remplissage en lecture ou en écriture, et en lecture à zéro pour les lignes non valides, vous ne pouvez donc pas du tout utiliser DRAM dans ce mode.


désolé, je suis un noob à l'assemblage, pourriez-vous s'il vous plaît expliquer cela plus simple? quel est un "mode" CPU? qu'est-ce que HBM? Comment définir un mode CPU? que sont les NDA?


@ThomasJager: le mode sans remplissage n'est pas un super secret; Coreboot (firmware x86 open source) l'utilise, et il peut même s'agir d'un registre de contrôle documenté ou d'un paramètre MSR. C'est ce à quoi j'ai pensé aussi. À quoi sert l'instruction INVD? / Cache- as-Ram (pas de mode de remplissage) Le code exécutable contient quelques détails.


@KGM: HBM = en.wikipedia.org/wiki/High_Bandwidth_Memory . Mais je me souvenais mal. La mémoire rapide de Xeon Phi qui peut être configurée comme un cache de dernier niveau visible sur le plan architectural ou transparent est " MCDRAM ", un concurrent de HBM. À 16 Gio, il est beaucoup plus gros que les caches L1 / L2 sur die.


c'est donc une sorte de "technologie future" remplaçant les anciens caches L1, L2, L3? Ou est-ce juste un supplément? Remplacera-t-il aussi les registres? (Je ne sais pas, peut-être que les futurs processeurs auront des milliers de registres.) À quelle vitesse sont ces méga caches par rapport aux registres?


Comme vous pouvez le voir dans l'article wiki que j'ai lié, c'est en plus des caches L1 et L2 de Xeon Phi. (MCDRAM est son L3.) C'est la même idée que les processeurs avec EDRAM comme cache L4, comme Intel avec des graphiques Iris Pro, ou ces processeurs de bureau Broadwell qui avaient EDRAM. C'est donc en plus, pas à la place, dans le cadre de la hiérarchie du cache.


3 Réponses :


2
votes

L'accès direct aux srams du cache n'a rien à voir avec le jeu d'instructions, si vous y avez accès, vous y avez accès et vous y accédez comme les concepteurs de la puce / du système l'ont implémenté. Cela peut être aussi simple qu'un espace d'adressage ou il peut s'agir d'un périphérique indirect comme l'accès où vous appuyez sur les registres de contrôle et que la logique accède à cet élément dans le cache pour vous.

Et cela ne signifie pas que tous les processeurs ARM peuvent accéder à leur cache de la même manière. (arm est une société IP et non une société de puces) mais cela peut signifier que non, vous ne pouvez pas le faire sur les x86 existants. Je sais que sur le produit dont je fais partie, nous pouvons le faire car nous avons ECC sur ces SRAM et avons une méthode d'accès pour initialiser les béliers à partir du logiciel avant d'activer le moniteur. Certains des srams vous pouvez le faire via des accès normaux, mais par exemple, le bras que nous utilisons a été implémenté avec un contrôle de parité et non ECC, nous avons donc ajouté ECC sur la SRAM et un accès de porte latérale pour init car en essayant de passer par le cache avec normal accès et obtenir une couverture à 100% était un PITA et la fin n'est pas la bonne solution.

A également travaillé sur un produit où le cache du contrôleur dram peut être utilisé en accès direct en tant que RAM sur puce, jusqu'à ce que le logiciel décide comment l'utiliser comme cache L2 ou comme RAM sur puce.

Cela a donc été fait et peut être fait, et ce sont des exemples isolés. Dans le cadre de la sélection des pièces, des tests mbist sont exécutés, mais souvent ceux-ci sont pilotés via jtag et ne sont pas directement disponibles pour le processeur et / ou le ram ne l'est pas, parfois le mbist peut être démarré et vérifié par un logiciel, mais le ram peut 't, et certaines implémentations, les concepteurs l'ont fait pour que le logiciel puisse tout toucher, y compris les balises ram.

Ce qui conduit à si vous pensez que vous pouvez faire un meilleur travail que le matériel et que vous voulez déplacer des choses, vous aurez probablement également besoin d'accéder à la balise RAM afin que vous puissiez tracer / conduire où vous voulez la ligne de cache , son statut, etc.

Basé sur ce commentaire:

Désolé, je suis un [débutant] en assemblage, pourriez-vous expliquer cela plus simplement? quel est un "mode" CPU? C'est quoi ce HBM? Comment définir un mode CPU? que sont les NDA? - KGM

Deux choses, vous ne pouvez pas faire mieux que le cache, et deux, vous n'êtes pas prêt pour cette tâche.

Même avec l'expérience, vous ne pouvez généralement pas faire mieux que le cache, si vous voulez manipuler le cache, vous utilisez les mêmes connaissances sur la façon dont vous écrivez votre code et où vous le placez en mémoire ainsi que sur l'emplacement des données. vous utilisez et la mise en œuvre logique peut mieux fonctionner pour vous. Graver des instructions et des cycles essayant de repositionner les éléments d'exécution ne va pas aider. Vous avez généralement besoin d'accéder à la conception à un niveau qui n'est pas accessible au grand public. Ainsi, un NDA (accord de non-divulgation), et même dans ce cas, il est extrêmement improbable que vous obteniez les informations dont vous avez besoin et / ou les gains seront minimes, ne fonctionnera que sur une seule implémentation et non sur toute la famille de produits, etc.

Plus intéressant est ce que tu penses pouvoir faire mieux et comment penses-tu pouvoir le faire? (comprenez également que beaucoup d'entre nous ici peuvent faire échouer toute implémentation de cache et s'exécuter plus lentement que si elle n'était pas là, même si vous créez un meilleur cache plus récent, par définition, cela n'améliore les performances que dans certains cas).


1 commentaires

pour des raisons de coût / performance, les srams dans le cache sont câblés de manière à ne pas être directement accessibles, il faudrait des bus supplémentaires, des signaux de contrôle, etc.pour ce faire et cela ne vaut généralement pas la peine, à moins que ce soit pour un problème d'initialisation spécifique ou pour un filtrage de puce d'une certaine sorte (ou une analyse de défaillance pour des cas d'utilisation spécialisés, bien que la logique supplémentaire crée un risque supplémentaire crée plus de défaillances). La réponse générale est non, il n'y a pas d'accès à ce niveau. Mais il existe des exceptions isolées.



4
votes

Sur la plupart des microarchitectures de la plupart des ISA, non, vous ne pouvez pas épingler une ligne dans le cache pour l'empêcher d'être expulsé. La seule façon d'utiliser le cache est de créer un cache transparent dans lequel vous chargez / stockez.

Bien sûr, un chargement normal amènera certainement une ligne de cache dans le cache L1d, au moins temporairement . Rien ne l'empêche d'être expulsé plus tard, cependant. par exemple. sur x86-64: mov eax, [rdi] au lieu de prefetcht0 [rdi] .

Avant que les instructions de prélecture dédiées n'existent, il était parfois possible d'utiliser un chargement brut comme prélecture (par exemple avant certains calculs de limites de boucle avant d'entrer dans une boucle qui commencerait à boucler sur un tableau). Pour des raisons de performances, les instructions de prélecture logicielle au mieux que le processeur peut ignorer sont généralement meilleures .

Un chargement brut a l'inconvénient de ne pas pouvoir se retirer du back-end en désordre tant que les données chargées ne sont pas arrivées. (Au moins, je pense que ce n'est pas le cas sur les processeurs x86 avec le modèle de mémoire fortement ordonné de x86. Des ISA faiblement ordonnés qui permettent des charges dans le désordre peuvent laisser la charge se retirer même si elle n'est pas encore vraiment terminée.) Instructions de prélecture du logiciel existe pour permettre la prélecture sous forme de indice sans goulot d'étranglement du processeur en attendant que le chargement se termine.

Sur les x86 modernes, l'expulsion forcée d'un cache est possible . Les magasins NT garantissent que sur les Pentium-M ou plus récents, ou les CPU après Pentium-M, j'oublie lesquels. De plus, clflush et clflushopt existent spécifiquement pour cela.

clflush n'est pas simplement un indice que le processeur peut tomber; il garantit l'exactitude des DIMM non volatiles comme Optane DC PM. Pourquoi CLFLUSH existe-t-il dans x86?

Être assuré, pas seulement un indice, le ralentit. Vous ne voulez généralement pas faire cela pour les performances. Comme le dit @old_timer, les instructions de gravure / cycles de micro-gestion du cache sont presque toujours une perte de temps. Laisser les choses au remplacement du pseudo-LRU du matériel et aux algorithmes de prélecture matérielle donne généralement de bons résultats sur le long terme. Cours. La prélecture SW peut aider dans quelques cas.


Xeon Phi peut configurer son MCDRAM comme un grand cache de dernier niveau, ou comme une" mémoire locale "architecturale visible qui fait partie de l'espace d'adressage physique. Mais entre 6 et 16 Gio, il est bien plus gros que les caches L1 / L2 sur die ou les caches L1 / L2 / L3 des processeurs grand public modernes.

De plus, les processeurs x86 peuvent fonctionner en mode cache-as-RAM sans remplissage, utilisé par le BIOS au début du démarrage avant de configurer les contrôleurs DRAM. Mais ce n'est vraiment aucun remplissage en lecture ou en écriture, et lecture à zéro pour les lignes non valides, vous ne pouvez donc pas du tout utiliser la DRAM lorsque le mode sans remplissage est activé. c'est-à-dire que seul le cache est disponible, et vous devez faire attention à ne pas expulser tout ce qui a été mis en cache. Il n'est utilisable à aucune fin pratique, à l'exception du démarrage anticipé.

À quoi sert l'instruction INVD? et Cache-as-Ram (pas de mode de remplissage) Le code exécutable contient quelques détails.

Je sais qu'il y a des instructions qui donnent des indices sur le "système de mise en cache", mais je ne suis pas sûr que cela soit suffisant car les indices pourraient être ignorés ou ils ne sont peut-être pas suffisants pour exprimer quoi que ce soit exprimable par un tel mouvement vers / de l'ordre du cache.


0 commentaires

5
votes

Peter Cordes a écrit:

Sur la plupart des microarchitectures de la plupart des ISA, non, vous ne pouvez pas épingler une ligne dans le cache pour l'empêcher d'être expulsé. La seule façon d'utiliser le cache est de créer un cache transparent dans lequel vous chargez / stockez.

C'est correct, mais les exceptions sont intéressantes ....

Il est courant dans les puces DSP («Digital Signal Processing») de fournir une capacité limitée de partitionner la SRAM entre les fonctionnalités de «cache» et de «mémoire de bloc-notes». Il existe de nombreux livres blancs et guides de référence sur ce sujet - un exemple est http: //www.ti.com/lit/ug/sprug82a/sprug82a.pdf . Dans cette puce, il y a trois blocs de SRAM - une petite SRAM "Level-1 Instruction", une petite SRAM "Level-1 Data" et une SRAM "Level-2" plus grande. Chacun des trois peut être partitionné entre le cache et la mémoire adressée directement, les détails dépendant de la puce spécifique. Par exemple, une puce peut n'autoriser aucun cache, 1/4 SRAM comme cache, 1/2 SRAM comme cache ou toute la SRAM comme cache. (Les ratios sont limités afin que les tailles de cache autorisées puissent être indexées efficacement.)

Le processeur IBM "Cell" (utilisé dans la PlayStation 3 de Sony, sortie en 2006) était une puce multicœur avec un cœur ordinaire à usage général et huit cœurs de coprocesseur. Les cœurs du coprocesseur avaient un jeu d'instructions limité, avec des instructions de chargement et de stockage qui ne pouvaient accéder qu'à leur mémoire "bloc-notes" privée de 128 Ko. Afin d'accéder à la mémoire principale, les coprocesseurs devaient programmer un moteur DMA pour effectuer une copie en bloc de la mémoire principale vers la mémoire du bloc-notes local (ou vice versa). Cette approche a fourni (et exigé) un contrôle parfait du mouvement des données, ce qui a abouti à (une très petite quantité) de logiciels très performants.

Certains GPU ont également de petites SRAM sur puce qui peuvent être configurées en tant que cache L1 ou en tant que mémoire locale explicitement contrôlée.

Tous ces éléments sont considérés comme "très difficiles" (ou pire) à utiliser, mais cela peut être la bonne approche si le produit nécessite un coût très bas, des performances totalement prévisibles ou une très faible puissance.


1 commentaires

Eh bien, intéressant ... Donc je vois que vous POUVEZ faire ça! Au moins avec certains CPU et GPU, et que cela augmente considérablement les performances! Cependant, je suis en quelque sorte inquiet de la part de marché de ces processeurs ... Sont-ils courants? Qu'en est-il d'AMD et d'Intel? Pouvez-vous faire de telles choses avec des processeurs AMD et / ou Intel à forte part de marché? si oui, ce serait très intéressant! (Je considère la part de marché sur les serveurs et / ou les mobiles et / ou les ordinateurs de bureau et / ou les ordinateurs portables. Un processeur capable de cela avec une part de marché élevée dans l'une de ces catégories serait intéressant. Surtout celui avec une part de marché élevée dans le serveur chat.)