7 votes

Comment pouvons-nous spécifier l'adresse physique d'une variable ?

Toutes les suggestions/discussions sont les bienvenues !

La question est en fait brève en tant que titre, mais je vais expliquer pourquoi j'ai besoin d'une adresse physique.


Contexte :

Ces jours-ci, je suis fasciné par le cache et les architectures multi-cœurs, et je suis maintenant curieux de savoir comment le cache influence nos programmes, dans un environnement parallèle.

Dans certains modèles de CPU (par exemple, mon Intel Core Duo T5800), le cache L2 est partagé entre les cœurs. Ainsi, si le programme A accède à la mémoire à l'adresse physique suivante

0x00000000, 0x20000000, 0x40000000...

et le programme B accède aux données à

0x10000000, 0x30000000, 0x50000000...

Étant donné que ces adresses partagent le même suffixe, l'ensemble correspondant dans la mémoire cache L2 sera fréquemment nettoyé. Nous nous attendons donc à voir deux programmes se battre l'un contre l'autre, en lisant lentement les données de la mémoire au lieu de la mémoire cache, bien qu'ils soient séparés dans des cœurs différents.

Je souhaite ensuite vérifier le résultat dans la pratique. Dans cette expérience, je dois connaître l'adresse physique au lieu de l'adresse virtuelle. Mais comment puis-je faire face à cette situation ?


La première tentative :

Manger un grand espace du tas, masquer, et obtenir l'adresse certaine.

Mon processeur dispose d'un cache L2 d'une taille de 2048 Ko et d'une associativité de 8, de sorte que des adresses physiques telles que 0x12340000, 0x12380000, 0x123c0000 sera lié au premier ensemble dans le cache L2.

int HEAP[200000000]={0};
int *v[2];
int main(int argc, char **argv) {

    v[0] = (int*)(((unsigned)(HEAP)+0x3fffc) & 0xfffc0000);
    v[1] = (int*) ((unsigned)(v[0]) + 0x40000); 

    // one program pollute v[0], another polluting v[1]
}

Malheureusement, avec "l'aide" de la mémoire virtuelle, les variables HEAP n'est pas toujours continue dans la mémoire physique. v[0] et v[1] peuvent être liés à différents jeux de caches.


La deuxième tentative

accès /proc/self/mem et essayer d'obtenir des informations sur la mémoire.

Hmm... il semble que les résultats concernent toujours la mémoire virtuelle.

7voto

Jonathon Reinhart Points 40535

Votre compréhension de la mémoire et de ces adresses est incomplète/incorrecte. Essentiellement, ce que vous essayez de tester est futile.

Dans le contexte des processus en mode utilisateur, pratiquement toutes les adresses que vous voyez sont des adresse virtuelle . C'est-à-dire une adresse qui n'a de sens que dans le contexte de ce processus. Le système d'exploitation gère la correspondance entre cet espace mémoire virtuel (propre à un processus) et les pages mémoire. À tout moment, ces pages de mémoire peut correspondent à des pages qui sont paginées (c'est-à-dire qui résident dans la mémoire vive physique) - ou elles peuvent être paginées et n'exister que dans le fichier d'échange sur le disque.

Ainsi, pour répondre à la Contexte par exemple, ces adresses proviennent de deux processus différents - cela ne veut absolument rien dire d'essayer de les comparer. La présence ou non de leur code dans l'un des caches dépend d'un certain nombre d'éléments, notamment de l'état d'avancement du processus. stratégie de remplacement du cache du processeur, les politiques de mise en cache activées par le système d'exploitation, le nombre d'autres processus (y compris les threads en mode noyau), etc.

Dans votre première tentative En revanche, vous n'arriverez pas à tester directement la mémoire cache du processeur. Tout d'abord, votre grand tampon ne sera pas sur le tas. Il fera partie de la section de données (spécifiquement le .bss) de l'exécutable. Le tas est utilisé pour le malloc() de la famille des allocations de mémoire. Deuxièmement, il importe peu que vous allouiez une énorme région de 1 Go, car bien qu'elle soit contiguë dans l'espace d'adressage virtuel de votre processus, c'est au système d'exploitation d'allouer des pages de mémoire virtuelle là où il le juge utile - ce qui peut être le cas dans les cas suivants pas sont effectivement contiguës. Encore une fois, vous n'avez pratiquement aucun contrôle sur l'allocation de la mémoire à partir de l'espace utilisateur. " Existe-t-il un moyen d'allouer de la mémoire physique contiguë à partir de l'espace utilisateur sous Linux ? ?" La réponse courte est non.

/proc/$pid/maps ne vous mènera nulle part non plus. Oui, il y a beaucoup d'adresses répertoriées, mais encore une fois, elles sont toutes dans l'espace d'adressage virtuel du processus $pid . Plus d'informations à ce sujet : Comment lire dans /proc/$pid/mem sous Linux ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X