IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Assembleur Discussion :

[Pentium] Optimisation - Alignement


Sujet :

Assembleur

  1. #21
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Tophinus, dasm, ne gère pas les far jump... Et j'arrive pas du tout a calculer ou est le code appelé par le jmp far.

  2. #22
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    (j'oubliais encore des trucs style utiliser le parity flag pour déterminer si deux bits sont égaux. Ca aussi c'est de l'asm inline qu'il faudrait)

  3. #23
    Membre actif

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    339
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 339
    Points : 279
    Points
    279
    Par défaut
    Effectivement, c'est ce que je t'avais dis dans le post, il ne "gère" pas les jump far comme il peut gérer les jmp near. J'ai pas encore trouvé de désassembleur qui permette de faire mieux que Dasm (surtout en rapidité et "convivialité"). Tu dois donc faire ton jmp far à la main (shift+F12).

    Petite note au cas où : Quand tu sauvegardes ton "projet" ou plutôt ton fichier désassemblé, il te crée deux nouveaux fichiers : .alf et .wpj. En fait, le .alf tu peux l'ouvrir avec wordpad et tu retrouveras le texte de ton fichier désassemblé (ça peut toujours servir).

    Je suis désolé que Dasm ne fasse pas les jmp far mais un des autres avantages que j'ai trouvé à Dasm c'est quand tu forces des intructions 32 bits en 16 bits (avec un db 66h ou un db 67h), il te laisse les codes. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    mov ecx,eax = db 66h,8bh,0c8h
    Eh bien, dans d'autres désassembleur tu auras seulement db 8bh,0C8h. Par contre de temps à autre, il désassemble mal le forcing en 32 bits. Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    out dx,eax = 66h,0EFh
    En fait il te l'affichera de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    out dx,ax = 66h,0EFh
    En gros, faut vérifier qu'il n'y ait pas un db66h qui traîne (en fait à partir du moment où tu trouves une ligne en 32 bits, là il faut penser à scruter après).

    Bon, j'ai été un peu long, désolé.

    Tu passes beaucoup de temps aussi sur ton émulateur. T'arrives à avoir le temps de t'y mettre ?
    Ma boule de cristal s'était éclaircie et puis plus rien. Alors je me suis mis à internet et maintenant j'ai plus de renseignements qu'avec cette satané boule .....

  4. #24
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    bah vi, je suis à la fac, alors j'ai le temps de m'y mettre :))

  5. #25
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    le problème, c'est que j'arrive pas a calculer ou va le far jump. Le code que je désassemble est enorme. Et l'adresse que je calcule ne tombe pas juste sur une instruction

  6. #26
    Invité
    Invité(e)
    Par défaut
    Il compile ca comment les switchs le compilateur ?? (j'ai du mal a croire que ca procedure en C pour le mod r/m est plus rapide que la mienne. (Déja au niveau de l'algorithme la mienne est plus rapide)
    Je n'ai pas dit que c'est plus rapide !! Je voulais juste te montrer comment on fait en C. Idem pour sahf.

    Quant a l'alignement des données, je peux le faire moi même. Si je me souviens bien, il y a des directives pour que l'assembleur le fasse.
    Oui via la directive ALIGN et il faut absolument le faire. De même pour les procédures alignées sur 16 octets, les labels alignés aussi.
    Les procs (depuis le 8086) ne supporte pas les données non alignés. Depuis il ne supporte pas bcp le code non-aligné non plus.
    Sur un 8086, pour lire un WORD dont l'adresse n'est pas divisible par 2, il le charge en deux fois !! Avec les procs actuels, c'est plus compliqué mais toujours trés pénalisant...

    J'ai vraiment du mal a voir, comment je pourrais faire mieux en C, d'autant que ca me prendrait encore beaucoup de temps, et que de l'asm inline + des fichiers générés aléatoirement + les optimisations d'algo qui donne des codes tordus, ce sera vraiment un suplice pour les adeptes du C a lire, et ca ne sera pas tellement portable.
    - En adaptant les algorithmes, il se peut que le C soit plus rapide: c'est n'est pas forcémenent le cas. Au point ou tu en es, il est effectivement trop tard pour penser au C...
    - Les fichiers ne sont pas générés alèatoirement, voyons...
    - Le code C que tu a vu est portable sur MAC par exemple (c'est du C ANSI). Il est clair qu'il doit être plus lent que le tien: on sacrifie la vitesse sur l'autel de la portabilié. Mais c'est intéressant d'émuler un x86 sur un PowerPC (ou autre).

    Donne moi des nouvelles des améliorations (s'il y en a) des call/ret et movzx.
    Je te conseille vivement d'éplucher "How To Optimize For The Pentium" dont je t'ai donné le lien.

  7. #27
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Oki merci, je vais lire tout ca (il faut aussi que je lise pour les amds, puis aussi il faut que je commprenne comment marche le flouage d'une image et l'alpha blending avec openGL...), comme c'est en anglais ca va me prendre pas mal de temps.

  8. #28
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Euh, je suis pas aller bien loin, il y a déja quelque chose que je comprends pas, c'est comment choisir l'alignement? 2, 4, 8, ou 16 ? Je comprends vraiment pas comment choisir. Et de toute facon, j'ai du mal a trouver comment utiliser l'alignment avec MASM. J'ai cru voir que le coded été aligné par défaut sur 4 octets... Mais concretement, il remplit d'une chaine de non-operation juste derrière les ret et les jmp ?

  9. #29
    Invité
    Invité(e)
    Par défaut
    Euh, je suis pas aller bien loin, il y a déja quelque chose que je comprends pas, c'est comment choisir l'alignement? 2, 4, 8, ou 16 ?
    Eh oui, c'est vite la prise de tête. Personnellement, j'aligne les routines sur 16 octets (c'est ce que fait VC).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ALIGN 16
    EmulerBloc		proc C NbInstructions:DWORD
    ...
    EmulerBloc endp
    Mais concretement, il remplit d'une chaine de non-operation juste derrière les ret et les jmp
    Oui, c'est la technique. Il remplit par des nop (ou équivalent style mov eax,eax, lea eax,[eax]: il y a toute une discution sur les neutral code fillers dans la doc d'AMD).
    L'avantage, c'est que ton jmp est aligné
    Exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
           jnz label
           mov eax, edx  
           shr eax, 2    ; par exemple
    ALIGN 8
    label: mov ecx , eax
    donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
           jnz label     
           mov eax, edx ;
           shr eax, 2    ;       
           nop           ;
           nop           ; autant de nop qu'il faut pour que label soit divisible par 8
           nop           ; comme je ici je n'en sait rien, j'en met 3
    label: mov ecx , eax
    Ici, label sera toujours divible par 8. Si tu change du code avant label, le nombre de nop va bien sûr changer...
    La règle est de n'aligner que les labels des boucles critiques (et plutôt sur 16 octets).
    Extrait de la doc AMD
    In program hot spots (as determined by either profiling or loop
    nesting analysis), place branch targets at or near the beginning
    of 16-byte aligned code windows. This guideline improves
    performance inside hotspots by maximizing the number of
    instruction fills into the instruction-byte queue and preserves Icache
    space in branch-intensive code outside such hotspots.
    Après si MASM fait déjà des alignements, c'est OK.

  10. #30
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Si je comprend bien, on aligne un dowrd ou un tableau de dword sur 4 octets pour que l'on puisse aller le chercher en une seule fois. Et on peut l'aligner sur 16, si on sait qu'on aura besoin des données qui suivent (cad pour des dwords, si on sait qu'on a besoin des 3 dwords qui suivent). Dans cee cas, pour un maximum d'opimisation assuré, il faudrait spécifier un alignement toujours de 16, le seul interet de le réduire, étant d'economiser la taille du programme (et donc parfois empecher de vider le cache si ca prend vraiemnt trop de place)

    Citation Envoyé par AMILIN
    La règle est de n'aligner que les labels des boucles critiques (et plutôt sur 16 octets).
    Je n'ai qu'une boucle, donc je peux ajouter un ALIGN16 juste devant début boucle. Il me semble que j'ai quand même tout interet à aligner toutes les destinations des jmp, cad vu que la table des labels TabIns16 pointe vers des blocs d'instructions, rajouter des ALIGN 16 devant chaque bloc.

    L'ennui aussi, c'est que j'ai des problèmes avec MASM, l'alignement est définit par la directive SEGMENT, mais l'aide ne precise pas son utilisation. De plus la directive ALIGN ne peut etre suivi que d'une puissance de 2 inferieure ou égale à l'alignement du segment. Quelqu'un sait comment utiliser l'alignment avec MASM ?

  11. #31
    Invité
    Invité(e)
    Par défaut
    C'est vrai que l'aide de MASM n'est pas prolixe ...
    Tu peut essayer ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
            .386      
     
    _TEXT   SEGMENT PUBLIC USE32 PAGE 'CODE'
     
    ALIGN   32
    truc  PROC
            mov         ecx,256
            mov         esi , esi
            ...
    ALIGN 16
      @@:   mov eax , 123456                  
            dec ecx
            jnz @b
     
            ret 
    truc  ENDP
     
    _TEXT   ENDS
     
            END

  12. #32
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      mov edx, [ebx]
      mov ax, dx
      shr edx, 16
    ca c'est pas un partial register stall, puisque les partials registers stall :

    You don't get a stall when reading a partial register after writing to the full register, or a bigger part of it

    Bon j'ai lu la doc à l'arrache, c'est un peu confuis dans ma tête, mais ca pourrait donner ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
      mov ecx, NbInstructions 
      jecxz FinBloc  ; au cas ou 
      mov edx, [ebx]
      push DebutBloc
     
    ALIGN 32
     
    DebutBloc:
      xor eax, eax		; 1 cycle supplémentaire entre le jnz et le call
      mov ax, dx
     
      call TbIns16[eax*4]
     
      mov edx, [ebx]	; 1 cycle suplémentaire entre le ret et le jnz
      dec ecx  
     
      jnz FinBloc

    Ou alors une version qui me semble bien moins bonne (pour les PII+ ca ralentit bcp, comme tu me l'avais dt pour les predictions des ret)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
      mov ecx, NbInstructions 
     
    ALIGN 32
     
    DebutBloc:
      dec ecx
      js FinBloc
     
      mov edx, [ebx]
      push DebutBloc
     
      xor eax, eax
      mov ax, dx
     
      jmp TbIns16[eax*4]

    Je me posait une autre question, pour ce qui concerne les flags, en particuliers pour les instructions qui modifient le carry flag. J'emploiyais jusqu'a la des structures du types :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      jc @f
      and MachineVirtuelle.r_flags, NOT CARRY FLAG
      ret
     
    @@:
      or MachineVirtuelle.r_flags, CARRY_FLAG
      ret
    qui crée des penalités dues au close jump et des misspredictions.

    J'ai du mal a voir si il est préférable de remplacer la structure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      mov ah, byte ptr MachineVirtuelle.r_flags
      sahf
     
      ...
     
      lahf
      mov byte ptr MachineVirtuelle.r_flags
    par une strtucture du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      push MachineVirtuelle.r_flags
      popf				;D'après la doc, pas d'exeptions, mais des consequences cachées ?
     
      ...
     
      pusf
      pop MachineVirtuelle.r_flags
    quitte a optimiser la pile, pour mon programme, vu que je sait, qu'elle contient l'adresse de retour de l'instruction, puis l'adresse de retour éventuelle du Mod r/m, je peux reserver 12 octets. Mais je ne suis pas certain qu'aucun élément exterieur ne pourrait me gener :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    Flags		dd ?
    PlancherPile	dd 2 dup(?)
    Pile		dd ?
     
    ...
     
    	mov Pile, esp
    	mov Flags, MachineVirtuelle.r_flags
    	mov esp, offsfet Pile
     
    	...	; boucle Instructions
     
    	pop esp
    	ret
     
    ...
     
      lea esp, [esp-8]
      popf
     
      ...
     
      pushf
      lea esp, [esp+8]
    Je sait pas si ca se fait, et ca a pas l'air d'etre tellement plus rapide.


    En ce equi concerne les movzx, il est conseillé de toujours les splitter si je me souviens bien, que ce soit pour le pairing ou pour les µops.

  13. #33
    Invité
    Invité(e)
    Par défaut
    Pour movzx, j'avais écrit
    Citation Envoyé par AMILIN
    (!!! sur des procs >= PPro !!!)
    De plus:
    1- Extrait de 'Intel Architecture Optimization"
    Pentium II and Pentium III processors provide special support to XOR a
    register with itself, recognizing that clearing a register does not depend on
    the old value of the register. Additionally, special support is provided for the
    above specific code sequence to avoid the partial stall. See “Partial Register
    Stalls” section for more information.
    The performance of the movzx instructions has been improved in order to
    reduce the prevalence of partial stalls on Pentium II and Pentium III
    processors. Use the movzx instructions when coding for these processors.
    2- Extrait de "AMD Athlon Processor x86 Code Optimization Guide" (valable aussi pour Duron)
    Use the MOVZX and MOVSX instructions to zero-extend and
    sign-extend byte-size and word-size operands to doubleword
    length. Typical code for zero extension that replaces MOVZX,
    as shown in Example 1 (Avoid), uses more decode and execution
    resources than MOVZX. It also has higher latency due to the
    superset dependency between the XOR and the MOV which
    requires a merge operation.

    Example 1 (Avoid):
    XOR EAX, EAX
    MOV AL, [MEM]

    Example 1 (Preferred):
    MOVZX EAX, BYTE PTR [MEM]
    Le cas que tu site (mov edx,[]) est effectivement différent mais tu peut toujours essayer. Movzx est DirectPath (en gros, il peut en décoder 3 par cycle) sur AMD (avec 1 cycle latence). C'est 1 µop sur P6.


    Pour POPF/PUSHF.
    La doc AMD signale que POPF est une instruction complexe (VectorPath) avec 15 cycles de latence (PUSHF seulement 4).
    Pour les P6, la doc "Optimization For..." signale une intruction complexe de 17 µops pour popf (sur 3 ports) et 16 pour pushf (sur 4 ports).
    sahf/lahf c'est seulement 1 µop sur P6. C'est VectorPath sur AMD avec respectivement 2 et 3 cycles de latences.
    Il n'y a pas photo...


    Pour la pile, regarde les docs Intel sur l'alignement de la pile.


    A+

  14. #34
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    le seul problème c'est que lahf et sahf ne sauvegarde pas la veleur du carry flag, et c'est assez lourd avec les sauts conditionels

  15. #35
    Invité
    Invité(e)
    Par défaut
    sahf ne sauvegarde pas la veleur du carry flag
    C'est le flag OF (Overflow Flag) qui n'est géré par sahf/lahf. Il en est de même pour DF et, moins important, TF et IF.
    OF n'est pas bcp utilisé dans les programmes (il est rare de voir des tests jo...). Pour DF (Direction Flag), c'est plus emmerdant: par exp si DF=0 l'instruction movsb/w/d incrémente esi et edi, sinon décrément.
    Toutefois, dans les cas réels, DF est rarement à 1...

    Si tu veux gérer correctement tous les flags, il ne te reste effectivement que pushf/popf...

  16. #36
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    vi c'est l'overflow pas le carry, désolé. Mais DF est rarement modifié par les instrtructions il me semble, sauf par STD ou CLD, deux instructions que j'emule presque aussi rapidement qu'un nop. Il vaut bien mieux pour les autres faire un saut conditionel suivant OF et modifier les flags en consequences, qu'utiliser pusf/popf d'après ce que j'ai compris. Donc je reste a l'ancienne methode

  17. #37
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Il y a deux petites chose que j'aimerais changer dans mon code. J'aimerais que tu me dises si je me trompe.

    D'une part, maintenant que je comprends mieux le fonctionement de la cache, j'ai l'impression, que dans

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    mov edx, [ebp]
    xor eax, eax
    mov ax, dx
    l'utilisation de edx est superflue : Si j'utilise ca c'est pour ne pas avoir a re-chercher une autre fois les données dans la mémoire. C'est utilie pour :

    - Les instructions ou il y a un mod r/m + disp8 ou disp16
    - Les instructions sans mod r/m mais avec un imm8 ou imm16 qui suit.

    Mais maintenant que je comprends mieux comment fonctionne la mémoire cache, je me dis, que se mov est inutile, est peut eviter des problèmes d'alignement des données, notement quand la "limite" de l'alignement tombe entre l'opcode-modrm et l'immediate ou le disp. De plus ca me permettrait de liberer edx.


    Sinon, j'aimerais savoir si en général dans les programmes (vieux ou recents) on trouve souvent des prefixes pour inverser la taille d'adressage. Parce que sinon, je vais me permetre de déplacer 12ko de mémoire a chaque fois qu'un tel prefixe a lieu.

  18. #38
    Invité
    Invité(e)
    Par défaut
    Petite erreur, dans ton code il d'agit de mov edx,[ebx]. Et d'ailleurs, tu n'utilise jamais ebp (sauf dans DOS.sam)!!!
    Voilà un registre de disponible !!! (d'ailleurs, j'aurais tendance à inverser ebp<->ebx dans ton code).

    C'est utilie pour :

    - Les instructions ou il y a un mod r/m + disp8 ou disp16
    - Les instructions sans mod r/m mais avec un imm8 ou imm16 qui suit.
    Dans tous les cas, autant libérer edx . Mais ne te focalise pas trop sur le cache.
    La structure de ton émulateur (et de n'importe lequel) ne permet pas trop ce genre d'optimisation: tu passe ton temps entre la RAM "émulée" et celle de la gestion de l'émulation (tables et autres). Et tu n'as pas trop le choix...

    Sinon, j'aimerais savoir si en général dans les programmes (vieux ou recents) on trouve souvent des prefixes pour inverser la taille d'adressage
    Citation Envoyé par Intel
    An address size prefix is used when you use 32-bit addressing in 16 bit mode or vice versa. This is seldom needed
    and should generally be avoided.
    C'est donc TRES rare et même déconseillé. Personnellement, je ne vois franchement pas l'utilité d'utiliser un mode d'adressage 16 bits en 32 bits (ou l'inverse):
    - mov eax , [di] en mp 32 bits quel intérêt... et quel plantage sous Windows. Si je me rapelle bien, les 4 premiers Mo (en adressage virtuel bien sur) sont réservés par le systême. Il doit y avoir contriantes similaires les autres OS en mp.
    - mov eax , [edi] en 16 bits se comprend un peu mieux (si edi<16bits). Mais l'intéret quand on peut mettre di..
    A mon avis, aucun compilateur n'engendre ce type de préfixe (sauf asm inline). Ce genre de "bizzarie" est le privilège du codeur ASM.

    As tu une amélioration de vitesse depuis le début de notre discution ?

  19. #39
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    vi, c'est vrai ct ebx. De toute facon pour l'indexation ebx est a peu près l'egal de ebp. Cela dit je comprends pas ce que tu essaie ded me dire avec la cache. A chaque instruction je dois utiliser entre 6 à 8 trtuc de 32 octets de la cache, je vide jamais rien, donc je pensais pouvoir utiliser cectte particularité de la cache.

    Je vais quand même émuler une floppée de programmes 16 bits, si ils ont des prefixe de taille d'adressage ca va pas etre rapide.

    Aucune idée de si il y a une amélioration. J'ai commencé a coder les instruictions d'operand size 32, et tant que j'ai pas fini, je pourrais pas savoir. De plus il faudrait que j'émule exactement les même instructions pour savoir, vu que la vitesse varie enormement, certaines instructions s'emulent trois fois plus lentement que d'autres.

    lol tu as regardé jusqu'a Dos.asm, j'aurais jamais pensé que quelqu'un pourrait y metre son nez un jour. Ils sont pas trop pitoyables les commentaires ?

  20. #40
    Invité
    Invité(e)
    Par défaut
    De toute facon pour l'indexation ebx est a peu près l'egal de ebp
    Oui, c'est équivalent même.
    Je pensais seulement que si tu remplace ebx par ebp (dont tu ne te sert pas je le rappelle), tu as un registre général de libre: ebp n'a pas de "forme" 8 bits comme ebx (bl,bh).
    Sur x86, le manque de registre se fait cruellement sentir...

    Exemple, ayant libéré ebx. La séquence avec OF
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
                            SaveFlags
                            jo @f
                            ResetFlag OVERFLOW_FLAG                       
                            ret
    @@:                     SetFlag OVERFLOW_FLAG
                            ret
     
    ; = sans les macros pour y voir plus clair
     
                            lahf
                            mov BYTE PTR MachineVirtuelle.r_flags, ah   
                            jo  @f
                            and WORD PTR MachineVirtuelle.r_flags, NOT OVERFLOW_FLAG
                            ret
    @@:                     or  WORD PTR MachineVirtuelle.r_flags, OVERFLOW_FLAG
                            ret
    peut se remplacer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     mov   bx , 0                                          ; ne pas détruire les flags
                                                           ; avec un xor bx,bx   
     mov   WORD PTR MachineVirtuelle.r_flags,OVERFLOW_FLAG ; r_flags <- 0x800 
                                                           ; se paire avec le mov bx
     lahf                                                  ; pairing impossible sur P6
     cmovo bx , WORD PTR MachineVirtuelle.r_flags          ; bx<-0x800 si OF=1 
     mov   bl , ah                                         ; byte inférieur des flags dans bl
     mov   WORD PTR MachineVirtuelle.r_flags, bx
     ret
    grâce aux instruction Conditional Mov (à partir des PPro et K6 pour AMD). Ca marche MAIS met les flags donc tu ne te sert pas actuellement (DF,IF,TF) à zéro.
    NB: L'instruction CMOV est assez contraigante et nécessite:
    - reg ou mem en source (ici un immediate aurais été mieux...)
    - destination = reg16 ou reg32
    J'ai testé les deux codes (en C+asm) vite fait sur mon Athlon. La deuxième version y est à peut près deux fois plus rapide.
    Attention: ce résultat dépend d'autres paramètres (notamment le contexte d'exécution) et il se peut que cela soit plus lent dans ton prog !!!
    Et d'ailleurs j'ai aussi essayé pushf / pop word ptr MachineVirtuelle.r_flags / ret qui s'est révélé aussi rapide que cmov... mais sur Athlon, pushf n'a que 4 cycles de latences (et popf 15 !)

    Cela dit je comprends pas ce que tu essaie ded me dire avec la cache
    Pour le cache de donnée, je voulais dire que tu ton programme passe son temps entre les "registres" de la structure X86 (donc qq octets) et
    ce qui est pointé par X86.RAM (taille 1Mo je crois) que ce soit pour lire les intructions ou les accès à la "RAM" du prog émulé.
    Toutefois, le nombre d'appels que tu fait à cette structure implique qu'elle doit être dans le L1 rapidement (si le proc n'est pas trop con !).
    Il n'y a pas grand chose à optimiser ici (il faudrait optimiser le prog que tu émule !! notamment ses accès mémoire !).

    Je vais quand même émuler une floppée de programmes 16 bits, si ils ont des prefixe de taille d'adressage ca va pas etre rapide.
    AUCUN compilateur 16 bits que j'ai eu l'occasion d'utiliser (Turbo Pascal 3->6, TC/C++) n'utilisait les instructions du 386 (ce qui d'ailleurs était pénalisant pour l'asm inline: il fallait se taper en hexa les instructions 32 bits).
    Donc par de préfixe de taille d'adressage. Je n'ai jamais rencontré de tel préfixe... Tu en as déjà rencontré avec ton émulateur (ou ailleurs) ?
    Citation Envoyé par re-Intel
    Using this prefix when the operands for an instruction do not reside in memory is reserved and may cause unpredictable behavior.
    Apparamment, ce préfixe doit être utilisé par le systême. Pas par des progs normaux.

    tu as regardé jusqu'a Dos.asm...Ils sont pas trop pitoyables les commentaires ?
    J'ai juste fait une recherche avec UtraEdit pout rechercher ebp. Les commentaires me semble acceptables...

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Optimisation de votre SGBDR et de vos requêtes...
    Par SQLpro dans le forum Langage SQL
    Réponses: 35
    Dernier message: 11/01/2013, 11h49
  2. JBuilder7 & JTable Colonne alignement
    Par Tonton Luc dans le forum JBuilder
    Réponses: 5
    Dernier message: 06/11/2002, 17h32
  3. [Datareport] Alignement
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 05/11/2002, 11h53
  4. [VB6] [Printer] Chiffres alignés à droite
    Par Laye dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 03/10/2002, 18h36
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo