Sur la Puce dsPIC famille de dispositifs de look-up table est stockée comme un ensemble d'instructions d'adresses dans le Flash lui-même. Effectuer de la recherche consiste à lire l'adresse de la mémoire Flash, puis l'appel de la routine. De faire l'appel ajoute une autre poignée de cycles de pousser le pointeur d'instruction et les autres bits et des bobs (par exemple, le réglage de la stack frame) de l'entretien ménager.
Par exemple, sur la dsPIC33E512MU810, à l'aide de XC16 (v1.24) le look de code:
lookUpTable[state]();
Compile (à partir du démontage de la fenêtre dans MPLAB-X):
! lookUpTable[state]();
0x2D20: MOV [W14], W4 ; get state from stack-frame (not counted)
0x2D22: ADD W4, W4, W5 ; 1 cycle (addresses are 16 bit aligned)
0x2D24: MOV #0xA238, W4 ; 1 cycle (get base address of look-up table)
0x2D26: ADD W5, W4, W4 ; 1 cycle (get address of entry in table)
0x2D28: MOV [W4], W4 ; 1 cycle (get address of the function)
0x2D2A: CALL W4 ; 2 cycles (push PC+2 set PC=W4)
... et de l' (vide, ne rien faire) la fonction compile:
!static void func1()
!{}
0x2D0A: LNK #0x0 ; 1 cycle (set up stack frame)
! Function body goes here
0x2D0C: ULNK ; 1 cycle (un-link frame pointer)
0x2D0E: RETURN ; 3 cycles
C'est un total de 11 instruction des cycles de surcharge pour l'un quelconque des cas, et ils prennent tous la même chose. (Remarque: Si la table ou les fonctions qu'il contient ne sont pas dans la même 32K programme word Flash page, il y aura une plus grande charge en raison d'avoir à obtenir l'Adresse de la Génération de l'Unité de lecture à partir de la page correcte, ou pour configurer le PC pour faire un appel long.)
Sur l'autre main, à condition que l'ensemble de l'instruction switch s'inscrit à l'intérieur d'une certaine taille, le compilateur génère un code qui fait un test et relative de la branche de deux instructions par cas en prenant trois (ou peut-être quatre) cycles par cas, jusqu'à celle qui est vrai.
Par exemple, l'instruction switch:
switch(state)
{
case FUNC1: state++; break;
case FUNC2: state--; break;
default: break;
}
Compile:
! switch(state)
0x2D2C: MOV [W14], W4 ; get state from stack-frame (not counted)
0x2D2E: SUB W4, #0x0, [W15] ; 1 cycle (compare with first case)
0x2D30: BRA Z, 0x2D38 ; 1 cycle (if branch not taken, or 2 if it is)
0x2D32: SUB W4, #0x1, [W15] ; 1 cycle (compare with second case)
0x2D34: BRA Z, 0x2D3C ; 1 cycle (if branch not taken, or 2 if it is)
! {
! case FUNC1: state++; break;
0x2D38: INC [W14], [W14] ; To stop the switch being optimised out
0x2D3A: BRA 0x2D40 ; 2 cycles (go to end of switch)
! case FUNC2: state--; break;
0x2D3C: DEC [W14], [W14] ; To stop the switch being optimised out
0x2D3E: NOP ; compiler did a fall-through (for some reason)
! default: break;
0x2D36: BRA 0x2D40 ; 2 cycles (go to end of switch)
! }
C'est une surcharge de 5 cycles si le premier cas est pris, 7 si le deuxième cas est pris, etc., ce qui signifie qu'ils se briser, même sur le quatrième cas.
Cela signifie que la connaissance de vos données au moment de la conception va avoir une influence significative sur le long terme de vitesse. Si vous avez un nombre important (plus de 4 cas) et tous, ils se produisent avec une fréquence similaire alors une look-up table) sera plus rapide dans le long terme. Si la fréquence des cas est significativement différente (par exemple, le cas 1 est plus probable que le cas 2, ce qui est plus probable que les cas 3, etc.) alors, si vous commandez le commutateur avec la plupart des cas probable d'abord, puis l'interrupteur sera plus rapide dans le long terme. Pour le cas de bord lorsque vous avez seulement quelques cas, le passage sera (probablement) être plus rapide de toute façon pour la plupart des exécutions et est plus lisible et moins sujette aux erreurs.
Si il n'y a que quelques cas dans le commutateur, ou certains cas, ne se produisent plus souvent que les autres, puis de faire le test et de la direction générale de l'interrupteur prendra probablement moins de cycles que l'utilisation d'une look-up table). D'autre part, si vous avez plus d'une poignée de cas qui se produisent avec une fréquence similaire puis le look-up sera probablement plus rapide que la moyenne.
Astuce: pour Aller avec le commutateur, sauf si vous savez le look-up sera certainement plus rapide et le temps d'exécution est important.
Edit: Mon exemple est un peu injuste, comme je l'ai ignoré la question d'origine et en doublé le "corps" de cas pour mettre en évidence l'avantage réel de l'aide d'un interrupteur sur un look-up. Si le commutateur de a à faire, et puis il n'a que l'avantage pour le premier cas!