2010-08-24 8 views

Répondre

0

Il y a une signification ou d'implication supplémentaire possible « accès au tableau à base de pointeur »:

Vous pouvez avoir un pointeur sur un tableau, plutôt qu'un tableau à une adresse fixe. En fait, en C/C++, un "pointeur sur un tableau" est généralement juste un pointeur vers le premier élément du tableau. En gros, vous avez un tableau qui est un paramètre à une fonction ou un pointeur vers un tableau qui est membre d'une struct ou classe:

void Foo(char a[]); 
    /*or*/ void Foo(char *a); 
struct Bar { int offset4bytes; char* a; }; 

En règle générale, lorsque vous voulez utiliser un tel tableau, la base l'adresse du tableau sera chargée dans un registre.

Maintenant que vous voulez accéder à l'élément i d'un tel réseau,

char tmp = a[i]; 

Disons que r1 contient l'adresse de tableau. (En fait, probablement un registre différent, spécifié par la convention d'appel, pour les paramètres de fonction.)

Disons que je réside dans le registre r2.

Et, pour faire bonne mesure, laissez tmp être r3.

Sur certains jeux d'instructions, par ex. Intel x86, il y a un mode d'adressage qui ressemble à

MOV r3, (r2,r1)4 

à savoir le mode d'adressage peut ajouter deux registres et un décalage (I arbitrairement ajouté un champ à l'exemple struct pour que je puisse montrer).

Heck, ils peuvent même échelle l'un des registres, le soi-disant registre d'index:

MOV r3, (r2*2,r1)4 

ou comme je préfère écrire

r3 := load(Memory[r2<<1+r1+4] 

MIPS, cependant, n'a pas ce genre de base + _index * échelle + mode d'adressage offset. La plupart des instructions d'accès à la mémoire MIPS sont limitées à enregistrer + décalage. Par conséquent, pour MIPS, vous pourriez avoir à faire

ADDU r10, r1,r1 ; dest on left. r10 = 2*r1 
    ADDU r11, r2,r10 
    LB r3,(r11)4 

dire que vous pourriez avoir à ajouter des instructions supplémentaires pour accomplir ce que RISC x86 fait dans une instruction CISC avec un mode d'adressage complexe. Cependant, un tel adressage n'est pas commun, et canm souvent être évité. En outre, même l'adressage d'un réseau à une adresse fixe peut nécessiter des instructions supplémentaires dans MIPS. Les instructions x86 peuvent avoir un décalage de mémoire de 32 bits - ce qui dans ce cas peut être une adresse absolue d'un tableau. Les instructions MIPS sont limitées à un décalage de 16 bits - les instructions MIPS ont une largeur fixe de 32 bits. Par conséquent, une instruction séparée peut être nécessaire même pour accéder à un tableau à une adresse fixe, typiquement pour charger les bits supérieurs de l'adresse dans un registre.

Et plus - MIPS a des instructions plus récentes comme LUXC1, qui ont des modes d'adressage reg + reg. Mais pas d'index mis à l'échelle, et pas de troisième composant de décalage.


En raison de ce mode d'adressage restreint, le code qui génère un compilateur naïf pour une lop comme

for(int i=0;i<N;i++) { 
     this->a[i] = 0; 
    } 

serait inefficace, si la boucle contient la séquence d'instructions multiples mentionné ci-dessus.

Une boucle telle que

for(char *p=this->a;p<&(this->a[N]);p++) { 
     *p=0; 
    } 

ou, ce qui revient

for(char *p=this->a;p<this->a+N;p++) { 
     *p; 
    } 

ou même parfois

for(i=-N,*p=this->a;i<0;i++,p++) { 
     *p=0; 
    } 

pourrait être plus efficace, parce que, par exemple dans les deux premiers il n'y aurait qu'une seule instruction pour faire le magasin. (Le dernier est généralement une victoire si traversant plusieurs tableaux

Maintenant, dans un exemple simple tout bon compilateur fera cette optimisation pour vous, mais parfois le compilateur préfère les accès à base de pointeur

+0

Peut-être pertinent:... De le fichier cflops.c dans la version Langer98 du banc d'essai Livermore Loops, http://www.aip.org/cip/langer.htm: Le compilateur AC, à partir de 1998, produit souvent un code plus rapide lors de l'accès à des données globales que lorsque l'accès aux données via un pointeur.Un effet secondaire d'utiliser des structures globales est que les performances observées dans ce benchmark peuvent être supérieures à celles de nombreux codes réels qui utilisent des pointeurs fortement . Un indicateur de compilateur déclarant qu'il n'y a aucun "alias de pointeur" dans un programme peut contourner cette perte de performance. –

0

Vous aurez un pointeur qui pointe vers le début du tableau de valeurs. Pour parcourir le tableau, vous utiliserez l'arithmétique du pointeur (généralement en ajoutant/soustrayant 1, 2 ou 4) pour faire avancer le pointeur vers l'élément suivant/précédent dans le tableau.

Questions connexes