2016-04-15 2 views
0

Ce qui suit est le code source simple c, où char x[2048] est une variable globale et func1 est appelé par thread1, func2 est appelé par thread2:ombles x [2048] et la ligne de cache d'émission

char x[2048]={0} , y[16]={0}; 

void func1(){ 
    strcpy(x,y); 
} 

void func2(){ 
    printf("(%s)\n",x); 
} 

int main(int argc, char **argv){ 
    strncpy(y,argv[1],sizeof(y)-1); 
} 

Dans cpu Intel , une ligne de cache a 64 octets, donc x devrait occuper 32 lignes de cache, mes questions sont les suivantes:

  1. tandis que thread1 appels func1, devraient al L 32 lignes de cache disponibles pour ce cache CPU jusqu'à ce que faire strcpy? (ou) compilateur sait qu'une seule ligne de cache suffit pour faire le travail?

  2. Alors que thread2 appel func2, doit toutes les 32 lignes de cache disponibles à cette cache du processeur jusqu'à ce que puis faire printf? (ou) le compilateur peut identifier une ligne de cache suffit?

+0

https://en.wikipedia.org/wiki/CPU_cache – user3386109

+2

Le compilateur est généralement complètement ignorant des détails des caches de matériel. – molbdnilo

+0

Qu'entendez-vous par "faire' strcpy/printf' "? Une ligne de cache ne fait rien, elle existe (ou pas). Et qu'est-ce qui est "disponible pour ce processeur"? – Leeor

Répondre

4

Je vous suggère de lire la page Wikipédia: https://en.wikipedia.org/wiki/CPU_cache

Un peu d'histoire:

  1. Normalement, la ligne de cache ($ L) sont transparents aux programmes. Donc, la plupart des programmeurs ne traitent pas directement avec la ligne de cache (introduisez-la, expulsez-la). Le processeur, une fois trouvé que le code/données ne sont pas dans $ L, bloquerait pour un tel accès à la mémoire et apporterait $ L à la demande.
  2. Bien qu'il existe des techniques de codage pour amener les données dans la ligne de cache dans le code (par exemple via l'instruction prefetch), normalement le compilateur ne sera pas assez intelligent pour le faire. est utilisé, il a déjà été expulsé), ou trop tard (le CPU doit toujours décrocher pour accéder à la mémoire).

Réponse à la question que vous:

  1. Non compilateur ne sait pas combien a besoin $ Ls être apporté (comment pourrait-il savoir si une donnée est déjà dans $ L ou non , alors soyez juste en sécurité et ne vous surpassez pas). Le compilateur vient juste de lancer, par exemple, une instruction MOV, et le CPU, en exécutant cette instruction, a trouvé que l'opérande n'est pas en $, donc les apporterait à la demande. Comme vous ne programmez que des copies jusqu'à '\ 0', le $ L y apporte des arrêts.
  2. Identique à # 1. Seuls $ Ls qui sont lus seront introduits et le compilateur n'a rien à voir avec ça.

Plus d'info:

  1. CPU prefetcher pourrait apporter Ls de $ supplémentaires en plus de ceux qui sont actuellement nécessaires. Par exemple, il pourrait apporter $ L en espérant la localisation des données.
  2. Certains programmes avancés utilisent des instructions de prélecture pour améliorer les performances du programme. Supposons que vous sachiez que votre code accèdera à un emplacement dans un avenir proche, que vous pouvez le pré-lire, et au moment où vous en avez besoin, il est déjà là, donc vous ne subirez pas de pénalité de $ L. Mais il est difficile de faire les choses correctement (vous devez connaître le modèle d'accès à la mémoire de votre code et insérer l'instruction prefetch au bon endroit.Certains logiciels de conception de code haute performance pour cela, mais encore une fois, c'est un sujet avancé).

https://en.wikipedia.org/wiki/Instruction_prefetch

0

sur x86 et x64 (ainsi que des armes modernes et d'autres CPU commun), le cache est totalement transparent pour les programmes en mode utilisateur. Par conséquent, strcpy effectue la première lecture, le processeur tire dans une ligne de cache automatiquement, strcpy se ferme sur le \0 et c'est fait. Même chose avec printf("%s",x).